我正在使用承诺(等待)。我有一个异步函数,必须等待异步请求:例如一个http请求。 HTTP请求可能会失败(超时或其他动机),但我需要回忆它直到成功或直到最大尝试次数(假设n次尝试),然后继续执行该功能。 我无法找到干净,井井有条的方法来做到这一点。 在伪代码下面:
async function func(){
//DO something before HTTP request
try{
let res = await http_request();
} catch(e){
//http request failed
//WHAT TO DO HERE TO CALL AGAIN THE HTTP REQUEST until success??
//or until max attempts == n?
}
//DO other stuff only after the http request succeeded
return;
}
这个想法是在最后返回一个promise,如果http请求和其余代码成功则解析,如果http请求尝试失败n次或其他错误,则拒绝。
PS:http请求是一个示例,但http_request()可以替换为任何其他异步函数。
答案 0 :(得分:2)
你可以做一个while循环,一旦成功请求就会中断,否则再次尝试。计数器可用于限制尝试次数。
async function func(){
let counter = 0;
while (counter < 100) {
try{
let res = await http_request();
break;
} catch(e){
counter++
continue;
}
}
return;
}
答案 1 :(得分:2)
您可以再次调用您的函数重试,然后您可以将其传递给重试计数器。您还应该在重试之前插入一个短暂的延迟,以避免锤击繁忙的服务器。
function delay(t, v) {
return new Promise(resolve => {
setTimeout(resolve.bind(null, v), t);
});
}
const kMaxAttempts = 10;
const kDelayBeforeRetry = 500;
async function func(cntr = 0){
//DO something before HTTP request
++cntr;
try{
let res = await http_request();
//DO other stuff only after the http request succeeded
return finalValue;
} catch(e){
// test to see if max retries have been exceeded
// also examine e to see if the error is retryable
if (cntr > kMaxAttempts || e is not a retryable error) {
throw e;
}
// retry after a short delay
return delay(kDelayBeforeRetry, cntr).then(func);
}
}
答案 2 :(得分:0)
我会以不同的方式对待请求。你试图只捕捉一个错误。您还需要处理失败的响应。哪个曾经请求您使用的API,http_request()很可能会返回响应和错误对象。您可以使用response.status === 500等检查失败的请求。如果响应因任何原因失败,您可以重试该请求。我经常看到这样做
http_request.GET(URL).then((response, error) => {
if (error) // retry
else if (response.status === 200 && response.body) // success
else if (response.status === 500) // retry
})
对于实际代码,您可以创建一个可重用的请求函数来执行if / else错误处理并获取HTTP方法和一些选项和数据等,并返回您的数据或错误的承诺 - 这是另一个共同模式。