general solution to retry a promise in javascript

后端 未结 1 750
抹茶落季
抹茶落季 2021-01-24 17:15

I try to give out a general solution for retrying a promise. Below is my way and comes an error of \"Uncaught (in promise)\".

How can I fix this problem?



        
相关标签:
1条回答
  • 2021-01-24 17:50

    The reason for what you asked about is that you're missing a call to resolve in your catch:

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

    ...and so you're creating a promise that is never handled by anything, and so if it rejects, you'll get an unhandled rejection.


    But, tryAtMost has a problem: It cannot work with the information you've given it, because it doesn't know what to try. You need to pass it an executor, not a promise, because it's the work of the executor that you need to retry. This also makes the function a lot simpler:

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

    Use:

    tryAtMost(4, (resolve, reject) => {
        // The thing to (re)try
    });
    

    Example:

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

    0 讨论(0)
提交回复
热议问题