Javascript 递归调用的异步函数将未定义的返回给被调用函数
我有一个从另一个异步锁代码调用的异步函数。asyn函数进行了一个关键的API调用,因此我需要使用重试逻辑来尝试执行它两次。运行两次后,它应该会断开 我的代码实现正确地中断了递归,但问题是在第二个异步函数可以执行异步锁内被调用的方法之前,异步锁得到了未定义的响应,因此中断了锁。来自第二个API调用的响应发生在锁外部。代码如下:Javascript 递归调用的异步函数将未定义的返回给被调用函数,javascript,node.js,recursion,async-await,Javascript,Node.js,Recursion,Async Await,我有一个从另一个异步锁代码调用的异步函数。asyn函数进行了一个关键的API调用,因此我需要使用重试逻辑来尝试执行它两次。运行两次后,它应该会断开 我的代码实现正确地中断了递归,但问题是在第二个异步函数可以执行异步锁内被调用的方法之前,异步锁得到了未定义的响应,因此中断了锁。来自第二个API调用的响应发生在锁外部。代码如下: //Callee function: return new Promise((resolve, reject) => {
//Callee function:
return new Promise((resolve, reject) => {
lock.acquire('Block_key', () => {
if(shouldRefresh()){
return getApiCall(
config,
flow,
retryCount
)
.then((response) => {
//debugger;
// Getting a undefined response
return resolve('Generated Success');
})
.catch((err) => {
return reject(err);
})
} else{
global.logger.info(`Returned from Cache.`);
// Remove cannot log token
global.logger.info(JSON.stringify(result));
return resolve(result);
}
},opts).then((response) => {
//debugger;
return resolve(response);
})
.catch((err) => {
return reject(err);
})
});
//Recursive Async function
const getApiCall = async function(config,flow, retryCount){
const hrstart = process.hrtime();
try{
let result = await _ouath2.getToken(util.getTokenConfig(config, flow,_scope)); // making the API call
let newResult = util.adjustExpiration(result, _refreshBufferTime);
_token = _ouath2.token.create(newResult);
return _token;
} catch(err){
if(retryCount === 1){ // hreaking the recursion
_log('Failed enough... Quitting now');
return err;
}else{
setTimeout(() => {
getApiCall(config,flow, retryCount-1); // making the recursive call
}, 3000)
}
}
}
正如@Adam在评论中指出的那样,我所做的错误是在递归块中进行调用时没有返回任何内容。注意,异步函数的响应只能是一个承诺,因此,对该函数的调用是在一个新的承诺块中进行的,并已解决/拒绝。这发送了正确的响应,而不是未定义的响应。正确的代码为: 如果(retryCount==1){
抛出错误;//在此处抛出错误很重要 }否则{ 返回新承诺((解决、拒绝)=>{ setTimeout(()=>{
getApiCall(配置、流、retryCount-1)。然后((响应)=>{ 返回解析(响应); }).catch((错误)=>{ global.logger.info('Error'+err); 退货拒绝(err); })
}, 1000) })
}它不是递归函数-您不会在“其他”中返回任何内容。您要做的是
返回新的承诺(res=>setTimeout(()=>res(getApiCall(…)),3000))
。快速键入伪代码,不保证没有语法错误。:)@亚当:哇。。成功了。但它对我来说仍然很神奇,为什么它会返回一个未定义的值呢?我知道我应该在else街区归还一些东西。从概念上讲,我哪里出了问题?如果你不返回任何东西,而只是在setTimeout中调用函数,那么调用getApiCall
的函数就不知道它需要再等待了,就它而言,getApiCall
完成并返回了未定义的。这有帮助吗?理解并且有意义。但是,如果我总是解析来自getApiCall的响应,那么调用它的函数将得到一个已解析的承诺,并且永远不会得到错误。因此,它总是进入.then((response)=>{//debugger;//获取未定义的响应返回resolve('Generated Success');}),即使我实际得到了一个错误。我尝试从调用中执行.then和resolve拒绝,但最终得到一个未处理的PromiserEjectionWarning。基本上,我尝试执行以下操作:if(retryCount==1){throw err;}else{return new Promise((resolve,reject)=>{setTimeout(()=>{getTokenApiCall(tokenConfig,flow,count-1)。然后((res)=>{return resolve(res);})。catch((err)=>{throw err;})}, 1000)