Вызываемая асинхронная функция рекурсивно возвращает неопределенную функцию вызываемой - PullRequest
0 голосов
/ 16 октября 2019

У меня есть асинхронная функция, вызываемая из другого кода асинхронной блокировки. Функция 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)
                }
            }
        }

1 Ответ

0 голосов
/ 17 октября 2019

То, что я делал не так, как @Adam указал в комментариях, ничего не возвращало во время вызова в рекурсивном блоке. Обратите внимание, что ответ от асинхронной функции может быть только обещанием, следовательно, вызов функции был сделан в новом блоке обещаний и разрешен / отклонен. Это отправило правильный ответ вместо неопределенного ответа. Правильный код:

if (retryCount === 1) {
throw err;// важно выбросить здесь ошибку} else {вернуть новое Promise ((разрешить, отклонить) => {setTimeout (() => {
getApiCall (config, flow, retryCount-1) .then ((response) => {return resolve (response);}). catch ((err) => {global.logger.info ('Error' + err); return reject (err);})
}, 1000)})}

...