簡體   English   中英

在節點js失敗后重試承諾自己

[英]Retry promise himself after fail in node js

我想在承諾中重試我的請求。 如果我總是將401錯誤作為循環,我想啟動刷新:(如果我在刷新時有401循環,直到200)

我試過這個:

const request = require('request');
let conf    = require('../conf');

let core_service = require('coreService');

let self = module.exports = {
    get_count_questions: function() {
        return new Promise((resolve, reject) => {
            request({
                method: 'GET',
                uri: 'http://api/count-questions',
                auth: {
                    'bearer': conf.token
                },
                json: true
            }, function (error, response, body) {
                if (!error && response.statusCode === 200) {
                    resolve(body);
                } else if (!error && response.statusCode === 401) {
                    core_service.refreshToken().then((data) => {
                        console.log('token refresh');
                        return self.get_count_questions();
                    })
                } else {
                    reject(error);
                }
            })
        });
    }
};

我試過'self.get_count_questions();' 沒有回報,但它不起作用。 我沒有錯誤消息,只是我的應用程序凍結。

我在我的console.log中看到“令牌刷新”,但在我的應用程序凍結之后......

編輯

我修改了它,它更好但刷新令牌非常慢。 就在401之前,我的應用停止了,大約1分40秒后,運行:

else if (!error && response.statusCode === 401) {
    console.log('need refresh token');
    core_service.refreshToken()
                .then((response) => {
                    console.log(response);
                    resolve(self.get_count_questions())
                } );
}

我的refreshToken函數:

refreshToken: function () {
    return new Promise((resolve, reject) => {
        request({
            method: 'GET',
            uri   : 'http://api/refresh',
            auth  : {
                'bearer': conf.token
            },
            json  : true
        }, function (error, response, body) {
            console.log('=====> refresh token <======');
            conf.token = body.data;
            console.log('new Token');
            console.log('=====> end refresh token <======');
            if (!error && response.statusCode === 200) {
                resolve('Refresh token successful');
            } else {
                reject('Error refresh');
            }
        })
    });
}

在此輸入圖像描述

如果我在每個請求上刷新我的令牌,我有一個問題:

if (!error && response.statusCode === 200) {
     core_service.refreshToken().then((data)=> {
         resolve(body);
     });

}

在此輸入圖像描述

您必須解決返回的承諾。 當您使用承諾解決時,您基本上會說,用該承諾的結果完成此承諾。

 var prom = function() { return new Promise((resolve, reject) => { console.log('request start') setTimeout(() => { console.log('request finish') let ran = Math.random(); if (ran < 0.1) resolve('success'); else if (ran >= 0.1 && ran < 0.98) setTimeout(() => { console.log('retry'); resolve(prom()); }, 500); else reject('error'); }, 500); }); }; prom().then(console.log.bind(console), console.log.bind(console)); 

所以你應該更新你的其他if塊如下:

else if (!error && response.statusCode === 401) {
  console.log('need refresh token');
  core_service.refreshToken()
    .then(() => resolve(self.get_count_questions()));
} 

你正在做一個遞歸調用,但你實際上從來沒有做過任何承諾。 因此,您的原始承諾永遠不會解決。

您需要將遞歸調用的promise(到refreshToken().then() )傳遞給resolve()

現在你幾乎擁有它。

然而:

return core_service.refreshToken()
                   .then(self.get_count_questions);

你將它返回到request()回調; 不使用該返回值。

相反,您需要通過將其傳遞給原始的resolve()函數來解決您對then()的新承諾的原始承諾:

resolve(core_service.refreshToken().then(...));

我知道這不是最佳解決方案,但它可能有所幫助

const request = require('request');
    let conf    = require('../conf');

    let core_service = require('coreService');

    let self = module.exports = {
        get_count_questions: function() {
            return new Promise((resolve, reject) => {
                request({
                    method: 'GET',
                    uri: 'http://api/count-questions',
                    auth: {
                        'bearer': conf.token
                    },
                    json: true
                }, function (error, response, body) {
             try{
                    if (!error && response.statusCode === 200) {
                        resolve(body);
                    } else if (!error && response.statusCode === 401) {
                       throw new Error(response.statusCode);
                    } else {
                        reject(error);
                    }
                 }catch(exc){if(exc === 401){
                            core_service.refreshToken().then((data) => {
                            console.log('token refresh');
                            return self.get_count_questions();
                        })      
                       }

                    }       
                })
            });
        }
    };

重試請求后,您需要調用初始解析/拒絕功能:

let self = module.exports = {
    get_count_questions: function() {
        return new Promise((resolve, reject) => {
            request({
                method: 'GET',
                uri: 'http://api/count-questions',
                auth: {
                    'bearer': conf.token
                },
                json: true
            }, function (error, response, body) {
                if (!error && response.statusCode === 200) {
                    resolve(body);
                } else if (!error && response.statusCode === 401) {
                    core_service.refreshToken().then((data) => {
                        console.log('token refresh');
                        self.get_count_questions().then((data) => {
                          // call initial resolve function
                          resolve(data);
                        }).catch((error) => {
                          // call initial reject function
                          reject(error);
                        });
                    }).catch((error) => {
                        // reject if refreshToken fails
                        reject(error);
                    });
                } else {
                    reject(error);
                }
            })
        });
    }
};

你還必須確保第二個調用實際上解析/拒絕並且不會落入另一個401.因為否則你有一個無限遞歸。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM