[英]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.