Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 递归调用的异步函数将未定义的返回给被调用函数_Javascript_Node.js_Recursion_Async Await - Fatal编程技术网

Javascript 递归调用的异步函数将未定义的返回给被调用函数

Javascript 递归调用的异步函数将未定义的返回给被调用函数,javascript,node.js,recursion,async-await,Javascript,Node.js,Recursion,Async Await,我有一个从另一个异步锁代码调用的异步函数。asyn函数进行了一个关键的API调用,因此我需要使用重试逻辑来尝试执行它两次。运行两次后,它应该会断开 我的代码实现正确地中断了递归,但问题是在第二个异步函数可以执行异步锁内被调用的方法之前,异步锁得到了未定义的响应,因此中断了锁。来自第二个API调用的响应发生在锁外部。代码如下: //Callee function: return new Promise((resolve, reject) => {

我有一个从另一个异步锁代码调用的异步函数。asyn函数进行了一个关键的API调用,因此我需要使用重试逻辑来尝试执行它两次。运行两次后,它应该会断开

我的代码实现正确地中断了递归,但问题是在第二个异步函数可以执行异步锁内被调用的方法之前,异步锁得到了未定义的响应,因此中断了锁。来自第二个API调用的响应发生在锁外部。代码如下:

 //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)