重试Javascript.Promise.reject有限次数或直到成功
我有一个函数说myMainFunction
,从客户端调用,这又调用mypromisified
函数。重试Javascript.Promise.reject有限次数或直到成功
场景: mypromisified
功能可以间歇性地失败,我需要调用一个延迟此功能(以指数增长),直到成功,或者直到最大没有达到的尝试。
我有什么到目前为止
下面的代码说明了我的情况,并重复自己,直到成功,但直到达到一定的数量就无限期地而不是试图
// called once from the client
myMainFuntion();
function rejectDelay(delay, reason) {
// call main function at a delayed interval until success
// but would want to call this only a limited no of times
setTimeout(() => {
myMainFuntion(); // calling main function again here but with a delay
}, delay);
}
function myMainFuntion() {
var delay = 100;
var tries = 3;
tryAsync().catch(rejectDelay.bind(null, delay));
}
function tryAsync() {
return new Promise(function(resolve, reject) {
var rand = Math.random();
console.log(rand);
if (rand < 0.8) {
reject(rand);
} else {
resolve();
}
});
}
while
循环里面的rejectDelay
肯定不会工作,因为计数器会在setInterval内部的实际函数执行之前增加,所以我不确定如何去做这件事?所以......
我试图promisifying
的setInterval
像这样明知会失败:(因为它不递减计数器,但不知道如何得到它的权利无论是。
function rejectDelay(delay, maximumTries, reason) {
return new Promise(function (resolve, reject) {
console.log(tries + ' remaining');
if (--maximumTries > 0) {
setTimeout(function() {
foo();
}, 500);
}
});
}
function myMainFunction() {
var delay = 100;
var maximumTries = 3;
tryAsync().catch(rejectDelay.bind(null, delay, maximumTries));
}
使用几个辅助函数,我用了很多,这个就变得非常容易
的“帮手”
Promise.wait = (time) => new Promise(resolve => setTimeout(resolve, time || 0));
Promise.retry = (cont, fn, delay) => fn().catch(err => cont > 0 ? Promise.wait(delay).then(() => Promise.retry(cont - 1, fn, delay)) : Promise.reject('failed'));
的代码:
function myMainFuntion() {
var delay = 100;
var tries = 3;
Promise.retry(tries, tryAsync, delay);
}
ES5版本的助手
Promise.wait = function (time) {
return new Promise(function (resolve) {
return setTimeout(resolve, time || 0);
});
};
Promise.retry = function (cont, fn, delay) {
return fn().catch(function (err) {
return cont > 0 ? Promise.wait(delay).then(function() {
return Promise.retry(cont - 1, fn, delay);
}) : Promise.reject('failed');
});
};
谢谢你一个简洁的解决方案:)。我明白'retry'上的递归调用,但无法让我的头绕过等待函数 - >我看到你正在返回一个新的Promise,但不能解析或拒绝相同的答案吗? - 在我的脑海里意味着'.then'上的'Promise.wait()'永远不会被调用?你介意多给我解释一下吗?提前谢谢 PS:我知道它是从撕裂工作:),我在这里https:// jsfiddle。net/jayas_godblessall/j50u8br9/- 但如上所述 - 不在我的脑海里工作:( – Jaya
“setTimeout”的第一个参数是一个函数来运行...它设置为'resolve'...因此解析在时间后被调用'ms –
ahh!gotcha!thank you! – Jaya
稍微不同的方法,它使用 “异步递归” 的调用函数中的嵌套函数退货承诺:
function retry(func, maxTries, delay) {
var reTry = 0;
return new Promise(function(resolve, reject) {
function callFunc() {
try
{
func().then(resolve, function(reason) {
if(++reTry >= maxTries) {
reject(reason);
}
else {
setTimeout(callFunc,
typeof delay=="function" ? delay(retry) : delay);
}
});
}
catch(e) {
reject(e);
}
}
callFunc();
});
}
// ******* run snippet to test ********
var retryCount = 0;
function getDelay(n) {
// return 100 * n*n + 500; // for example
++ retryCount;
return 100; // for testing
}
function testFunc() {
return Math.random() < 0.8 ? Promise.reject("too many tries") : Promise.resolve("success");
}
retry(testFunc, 5, getDelay).then(
function(data) { console.log("data: %s, retryCount %s", data, retryCount);},
function(reason){console.log("reason: %s, retryCount %s", reason, retryCount);}
)
相关的答案:[无极重试设计模式](http://stackoverflow.com/questions/38213668/promise-retry-design-patterns/38214203#38214203)和[重试一个承诺步骤]( http://stackoverflow.com/questions/37993365/retry-a-promise-step/37995874#37995874) – jfriend00