如何使用 setInterval(with clearInterval)使用 Bluebird Promises 发送请求?
How to use setInterval (with clearInterval) to send requests using Bluebird Promises?
我正在使用 node-request 向服务器发送请求以获取一些报告。问题是服务器需要一些时间来生成报告,因此它会以报告状态进行响应。我正在使用 setInterval()
函数检查报告状态,并在服务器发送 ready
响应时使用 clearInterval()
。但是使用这种方法,即使在我使用 clearInterval
之后,早期请求的响应仍在继续,并且响应处理程序 运行 一次又一次。这不会造成很大的伤害,但我仍然相信它可以做得更好。
这是我的代码:
checkForReportReady = setInterval =>
@request URL, options, (err, res, body) =>
console.log err if err
body = JSON.parse body
if body['status'] is 'ready'
clearInterval checkForReportReady
@processReport body
, 1000
我需要什么:发出请求,等待响应,检查状态,如果状态不是ready
- 超时后再次请求,重复直到响应的状态代码是 ready
。如果状态为就绪 - 退出循环(或清除间隔)和 运行 @processReport
.
我尝试了promisified request,然后放入setInterval
,结果还是一样
P.S。我不控制服务器,所以我不能改变它响应或处理报告的方式。
您似乎可以在响应处理程序中使用 setTimeout()
:
function checkForReportReady() {
request(URL, options, function(err, res, body) {
if (err) {
console.log(err);
} else {
if (body.status === "ready") {
processReport(body);
// do any other processing here on the result
} else {
// try again in 20 seconds
setTimeout(checkForReportReady, 20*1000);
}
}
});
}
这会运行一个请求,等待响应,检查响应,如果准备好了就处理,如果没有准备好,等待一段时间再发起另一个请求.它永远不会同时处理超过一个请求。
如果你想使用 Bluebird 承诺,你也可以这样做,尽管在这种情况下它似乎并没有特别改变复杂性:
var request = Promise.promisifyAll(require('request'));
function checkForReportReady() {
return request(URL, options).spread(function(res, body) {
if (body.status === "ready") {
return body;
} else {
// try again in 20 seconds
return Promise.delay(20 * 1000).then(checkForReportReady);
}
});
}
checkForReportReady().then(function(body) {
processReport(body);
}, function(err) {
// error here
});
我建议不要将请求放入间隔回调中。当它们 a) 失败 b) 花费比间隔更长的时间时,这会变得很难看。
而是将 setTimeout
放入成功处理程序中,并在(且仅当)收到响应后重试。
这对于承诺来说相当容易:
request = Promise.promisifyAll require 'request'
getReport = () =>
request URL, options
.spread (res, body) =>
body = JSON.parse body
if body.status is 'ready'
body
else
Promise.delay 1000
.then getReport # try again
getReport().then(@processReport, (err) -> console.log(err))
我正在使用 node-request 向服务器发送请求以获取一些报告。问题是服务器需要一些时间来生成报告,因此它会以报告状态进行响应。我正在使用 setInterval()
函数检查报告状态,并在服务器发送 ready
响应时使用 clearInterval()
。但是使用这种方法,即使在我使用 clearInterval
之后,早期请求的响应仍在继续,并且响应处理程序 运行 一次又一次。这不会造成很大的伤害,但我仍然相信它可以做得更好。
这是我的代码:
checkForReportReady = setInterval =>
@request URL, options, (err, res, body) =>
console.log err if err
body = JSON.parse body
if body['status'] is 'ready'
clearInterval checkForReportReady
@processReport body
, 1000
我需要什么:发出请求,等待响应,检查状态,如果状态不是ready
- 超时后再次请求,重复直到响应的状态代码是 ready
。如果状态为就绪 - 退出循环(或清除间隔)和 运行 @processReport
.
我尝试了promisified request,然后放入setInterval
,结果还是一样
P.S。我不控制服务器,所以我不能改变它响应或处理报告的方式。
您似乎可以在响应处理程序中使用 setTimeout()
:
function checkForReportReady() {
request(URL, options, function(err, res, body) {
if (err) {
console.log(err);
} else {
if (body.status === "ready") {
processReport(body);
// do any other processing here on the result
} else {
// try again in 20 seconds
setTimeout(checkForReportReady, 20*1000);
}
}
});
}
这会运行一个请求,等待响应,检查响应,如果准备好了就处理,如果没有准备好,等待一段时间再发起另一个请求.它永远不会同时处理超过一个请求。
如果你想使用 Bluebird 承诺,你也可以这样做,尽管在这种情况下它似乎并没有特别改变复杂性:
var request = Promise.promisifyAll(require('request'));
function checkForReportReady() {
return request(URL, options).spread(function(res, body) {
if (body.status === "ready") {
return body;
} else {
// try again in 20 seconds
return Promise.delay(20 * 1000).then(checkForReportReady);
}
});
}
checkForReportReady().then(function(body) {
processReport(body);
}, function(err) {
// error here
});
我建议不要将请求放入间隔回调中。当它们 a) 失败 b) 花费比间隔更长的时间时,这会变得很难看。
而是将 setTimeout
放入成功处理程序中,并在(且仅当)收到响应后重试。
这对于承诺来说相当容易:
request = Promise.promisifyAll require 'request'
getReport = () =>
request URL, options
.spread (res, body) =>
body = JSON.parse body
if body.status is 'ready'
body
else
Promise.delay 1000
.then getReport # try again
getReport().then(@processReport, (err) -> console.log(err))