Promise重试函数
问题描述
需要实现一个retry函数,这个函数的输入是一个promise函数fn,重试次数times。
- 对于函数
fn,他是一个异步函数。 - 执行成功
resolve(value)时,直接返回结果value。 - 如果执行失败
reject(err),则可以尝试最多times重试机会。
问题解决
- 可以肯定的是,对于
retry函数来说,它也是一个异步函数。所以retry返回一个Promise,整体结构是下面这样子。
const retry = (fn, times) => {
return new Promise((res,rej)=> {
// 写入代码
})
}
- 我们将
fn函数封装成一次尝试attempt,其中包括失败和成功的处理。并且立即开始一次尝试attempt()
const retry = (fn, times) => {
return new Promise((res,rej)=> {
const attempt = () => {
fn().then(value => {
// 成功
}).catch(err => {
// 失败
})
}
attempt(); // 立即执行
})
}
- 如果成功的话,我们直接将结果返回。
// 省略...
fn().then(value => {
res(value)
}).catch(err => {
// 失败
})
// 省略...
- 如果失败的话,我们需要判断尝试机会
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);
});