Roc*_*bob 4 asynchronous node.js do-while
我有一个函数向API发出请求.有时API会出现一些小问题,并且不时有一两秒钟可用,导致出现错误,我想再次调用该函数.由于此回调后还有另外70~80行代码,我不想用一个分割流if(error) <do the same stuff> else <as here>
在尝试了一段时间后,我最终使用了do-while(错误)循环,它可以阻止.有这样的异步方式吗?
我的代码(简化为泛化):
//This is the request part
function bar(j, callback){
j++;
//simulated error
if(j<=10){
return( callback('dont', j) );
}
//simulated success
else{
return( callback(null, j) );
}
}
//This is the main function - part of a bigger piece in my code
function foo(){
var i = 0;
var err = 'yes'; //else we'd get an 'err is not defined'
do{
bar(i, function(error, j){
i = j
err = error;
if(error){
console.log(i);
}
else{
return( console.log('done it!') );
// There's more here in my code
}
});
} while (err);
console.log('I blocked');
}
foo();
Run Code Online (Sandbox Code Playgroud)
编辑:
对于那些感兴趣的人,这是输出:
1
2
3
4
5
6
7
8
9
10
done it!
I blocked
Run Code Online (Sandbox Code Playgroud)
我建议你为你的手术做一个功能.如果失败,则设置一个短计时器,并在该计时器触发后重试.这将为您提供重试与服务器中的其他代码之间的异步行为.
function requestRetry(url, data, retryTimes, retryDelay, callback) {
var cntr = 0;
function run() {
// try your async operation
request(..., function(err, data) {
++cntr;
if (err) {
if (cntr >= retryTimes) {
// if it fails too many times, just send the error out
callback(err);
} else {
// try again after a delay
setTimeout(run, retryDelay);
}
} else {
// success, send the data out
callback(null, data);
}
});
}
// start our first request
run();
}
requestRetry(someUrl, someData, 10, 500, function(err, data) {
if (err) {
// still failed after 10 retries
} else {
// got successful result here
}
});
Run Code Online (Sandbox Code Playgroud)
这是一个相当简单的重试方案,它只是在固定的时间间隔内重试固定的次数.更复杂的方案实现了退避算法,它们以相当快的重试开始,但是在最初的几次故障之后重试之间的较长时间后退到服务器以便更好地恢复.如果有很多客户都在进行快速重试,那么只要服务器出现打嗝,您就会遇到雪崩故障,因为所有客户突然开始快速重试,这会让您的服务更加麻烦处理所有这些请求.退避算法旨在使服务器更好地防止雪崩故障并使其更容易恢复.
如果您在服务停止一段时间之后等待服务重新上线,那么退避计划也更合适.