Promise重试函数

1,637 阅读1分钟

Promise重试函数

问题描述

需要实现一个retry函数,这个函数的输入是一个promise函数fn,重试次数times

  • 对于函数fn,他是一个异步函数。
  • 执行成功resolve(value)时,直接返回结果value
  • 如果执行失败reject(err)则可以尝试最多times重试机会

问题解决

  1. 可以肯定的是,对于retry函数来说,它也是一个异步函数。所以retry返回一个Promise,整体结构是下面这样子。
 const retry = (fn, times) => {
   return new Promise((res,rej)=> {
     // 写入代码
   }) 
 }
  1. 我们将fn函数封装成一次尝试attempt,其中包括失败和成功的处理。并且立即开始一次尝试attempt()
 const retry = (fn, times) => {
   return new Promise((res,rej)=> {
     const attempt = () => {
       fn().then(value => {
         // 成功
       }).catch(err => {
         // 失败
       })
     }
     attempt(); // 立即执行
   }) 
 }
  1. 如果成功的话,我们直接将结果返回。
 // 省略...
       fn().then(value => {
         res(value)
       }).catch(err => {
         // 失败
       })
 // 省略...
  1. 如果失败的话,我们需要判断尝试机会times是否用完。
 // 省略...
       fn().then(value => {
         res(value)
       }).catch(err => {
         if(times > 0) {
           times --;
           attempt()
         } else rej("机会用光了")
       })
 // 省略...

总结

以上完整的代码就是

 const retry = (fn, times) => {
   return new Promise((res, rej) => {
     const attempt = () => {
       fn().then(res).catch((error) => {
           times-- > 0 ? attempt() : rej("机会用光了");
         });
     };
     attempt();
   });
 };

加上测试代码

 let getNum = function () {
   console.log("函数执行一次");
   return new Promise((res, rej) => {
     let num = Math.random() * 10;
     num < 2 ? res("数字小于2") : rej("数字大于2");
   });
 };
 ​
 retry(getNum, 3)
   .then((mes) => {
     console.log(mes);
   })
   .catch((err) => {
     console.log(err);
   });