我正在使用Facebook图形API,它通常会返回一个未知错误'消息,如果我在几秒钟之后重试帖子,我会发现它没有问题。
此代码将调用postAsync,在收到成功响应后,它将使用新的Promise解决该问题,否则它将递增尝试计数器并再次调用该函数。
function guaranteedPost(endpointId, wallPost, attempts){
attempts = attempts || 0
++attempts
return graph.postAsync(endpointId + '/feed', wallPost).then(function(response){
return new Promise.resolve(response)
}).catch(function(error){
setTimeout(function(){
console.log(attempts)
console.log(error)
if(attempts == 2){
return Promise.reject('Too many attempts')
}
else{
return guaranteedPost(endpointId, wallPost, attempts)
}
}, 5000)
});
}
guaranteedPost(endpointId, wallPost, 0).then(function(value){
console.log(value)
})
.catch(function(error){
console.log(error)
})
我希望能够使用这样的代码,我将其称为guaranteePost,并将响应或单个“太多”尝试登录到控制台。错误信息。但是,目前我收到的是我的输出:
undefined
Unhandled rejection Error: Too many attempts
因此,第一个调用返回undefined,第二个调用没有错误处理,就会爆炸。
另外,我想在更大的函数的上下文中使用它,它可以访问前面定义的变量,因此我不想将错误和成功处理转移到它们自己的函数中。
我无法帮助,但觉得我非常接近,但这是在一两次完整的重构之后,我仍然无法确定它。我该如何正确设计?
答案 0 :(得分:1)
将超时逻辑拆分为实际的承诺,然后返回。通过执行setTimeout
之类的操作,您可以捕获错误并且不返回任何内容,然后排队新请求,无需捕获其失败。承诺都是关于链接的。
function delay(ms){
return new Promise(function(resolve){
setTimeout(resolve, ms);
});
}
function guaranteedPost(endpointId, wallPost, attempts){
attempts = attempts || 0
++attempts
return graph.postAsync(endpointId + '/feed', wallPost).then(function(response){
return new Promise.resolve(response)
}).catch(function(error){
// Return a promise that waits a little bit, then tries again.
return delay(5000).then(function(){
console.log(attempts)
console.log(error)
if(attempts == 2){
return Promise.reject('Too many attempts')
}
else{
return guaranteedPost(endpointId, wallPost, attempts)
}
})
});
}
我还会简化这段代码:
function delay(ms){
return new Promise(function(resolve){
setTimeout(resolve, ms);
});
}
function guaranteedPost(endpointId, wallPost, attempts){
return graph.postAsync(endpointId + '/feed', wallPost)
.catch(function(error){
if (attempts === 2) throw new Error('Too many attempts');
// Return a promise that waits a little bit, then tries again.
return delay(5000).then(function(){
return guaranteedPost(endpointId, wallPost, (attempts | 0) + 1);
})
});
}