在javascript中重试承诺的一般解决方案

ikz*_*fr0 2 javascript es6-promise

我尝试给出重试承诺的通用解决方案。以下是我的方式,并出现“未捕获(承诺)”的错误。

我该如何解决这个问题?

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)
})
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 5

原因你问什么是你错过了一个电话给resolvecatch

.catch(err => {
    if (tries > 0) {
        console.log(`tries with ${tries}`);
        resolve(tryAtMost(--tries, promise)); // <=== ****
    }
    else {
        reject(err)
    }
})
Run Code Online (Sandbox Code Playgroud)

...所以你正在创建一个永远不会被任何东西处理的承诺,所以如果它拒绝,你会得到一个未处理的拒绝。


但是tryAtMost有一个问题:它无法使用您提供的信息,因为它不知道该尝试什么。您需要向它传递一个执行程序,而不是一个承诺,因为您需要重试执行程序的工作。这也让函数变得简单了很多:

function tryAtMost(tries, executor) {
    --tries;
    return new Promise(executor)
        .catch(err => tries > 0 ? tryAtMost(tries, executor) : Promise.reject(err));
}
Run Code Online (Sandbox Code Playgroud)

用:

tryAtMost(4, (resolve, reject) => {
    // The thing to (re)try
});
Run Code Online (Sandbox Code Playgroud)

例子:

.catch(err => {
    if (tries > 0) {
        console.log(`tries with ${tries}`);
        resolve(tryAtMost(--tries, promise)); // <=== ****
    }
    else {
        reject(err)
    }
})
Run Code Online (Sandbox Code Playgroud)