我试图给出重试承诺的一般解决方案。以下是我的方式,并且出现了#34; Uncaught(承诺)"。
的错误如何解决此问题?
function tryAtMost(maxRetries, promise) {
let tries = maxRetries
return new Promise(function(resolve, reject) {
promise.then((result) => {
resolve(result)
})
.catch(err => {
if (tries > 0) {
console.log(`tries with ${tries}`)
tryAtMost(--tries, promise);
} else {
reject(err)
}
})
})
}
tryAtMost(3, promise).then(result => {
console.log(result)
})
.catch(err => {
console.log(err)
})
答案 0 :(得分:3)
您询问的原因是您错过了resolve
中catch
的来电:
.catch(err => {
if (tries > 0) {
console.log(`tries with ${tries}`);
resolve(tryAtMost(--tries, promise)); // <=== ****
}
else {
reject(err)
}
})
...所以你创造了一个永远不会被任何东西处理的承诺,所以如果拒绝,你将得到一个未处理的拒绝。
但是,tryAtMost
有一个问题:它无法使用您提供的信息,因为它不知道该尝试什么。你需要传递一个执行者而不是一个承诺,因为这是你需要重试的执行者的工作。这也使功能更加简单:
function tryAtMost(tries, executor) {
--tries;
return new Promise(executor)
.catch(err => tries > 0 ? tryAtMost(tries, executor) : Promise.reject(err));
}
使用:
tryAtMost(4, (resolve, reject) => {
// The thing to (re)try
});
示例:
function tryAtMost(tries, executor) {
console.log(`trying, tries = ${tries}`);
--tries;
return new Promise(executor)
.catch(err => tries > 0 ? tryAtMost(tries, executor) : Promise.reject(err));
}
tryAtMost(4, (resolve, reject) => {
const val = Math.random();
if (val < 0.3) {
resolve(val);
} else {
reject(val);
}
})
.then(result => console.log(result))
.catch(err => console.error(err));