在节点js失败后重试承诺自己

时间:2017-09-08 13:36:34

标签: javascript node.js promise es6-promise

我想在承诺中重试我的请求。如果我总是将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');
            }
        })
    });
}

enter image description here

如果我在每个请求上刷新令牌,我就会遇到问题:

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

}

enter image description here

5 个答案:

答案 0 :(得分:11)

您必须解决返回的承诺。当您使用承诺解决时,您基本上会说,用该承诺的结果完成此承诺。

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

所以你应该更新你的else if if this:

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

答案 1 :(得分:3)

您正在进行递归通话,但您实际上从未对其承诺做任何事情。因此,您原来的承诺永远不会解决。

您需要将递归调用(至refreshToken().then())的承诺传递给resolve()

答案 2 :(得分:2)

现在你几乎拥有它。

然而:

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

您将其返回request()回调;不使用该返回值。

相反,您需要通过将其传递给原始then()函数来解析您对resolve()新承诺的原始承诺:

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

答案 3 :(得分:1)

我知道这不是最佳解决方案,但可能会有所帮助

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();
                        })      
                       }

                    }       
                })
            });
        }
    };

答案 4 :(得分:-1)

重试请求后,您需要调用初始解析/拒绝功能:

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.因为否则你有一个无限的递归。