const p = () =>
new Promise((resolve, reject) =>
setTimeout(() => {
let a = Math.random();
let flag = a > 0.1 ? 0 : 1;
console.log(flag);
flag === 1 ? resolve(flag) : reject(flag);
}, 1000)
);
// 大同小异的实现方式
/* Promise.retry = function (promiseFn, times = 3) {
return new Promise(async (resolve, reject) => {
while (times--) {
try {
let ret = await promiseFn();
resolve(ret);
break;
} catch (error) {
if (!times) reject(error);
}
}
});
}; */
/* Promise.retry = function (promiseFn, times = 3) {
return new Promise((resolve, reject) => {
let count = 0;
let action = function () {
promiseFn()
.then(resolve)
.catch((err) => {
count++;
if (count >= times) {
reject(err);
} else {
action();
}
});
};
action();
});
}; */
Promise.retry = function (asyncFn, times = 3) {
let count = 0;
function executeFn() {
return new Promise((resolve, reject) => {
resolve(asyncFn());
})
.then((res) => {
return Promise.resolve(res);
})
.catch((err) => {
count++;
if (count >= times) {
return Promise.reject(err);
} else {
return executeFn();
}
});
}
return executeFn();
};
Promise.retry(p, 3).then(() => {
console.log("okkk");
});
1.2 任务中断
批量执行异步任务,有任务返回 false 就中断执行并返回结果。
let asyncFn = (val) => {
return new Promise((resolve) => {
setInterval(() => {
resolve(val);
}, 1000);
});
};
let tasks = [true, false, false].map((v) => () => asyncFn(v));
// 基础 for 循环
/* async function run() {
for (let i = 0; i < tasks.length; i++) {
const task = tasks[i];
let res = await task();
if (!res) {
return false;
}
}
return true;
} */
// for of
async function run() {
for (const task of tasks) {
let res = await task();
if (!res) {
return false;
}
}
return true;
}
async function main() {
let result = await run();
console.log("result", result);
}
main(); // result false
1. 玩转异步
1.1 异步重试
异步任务多次重试尝试获取正确信息,可以分为按时间和按次数两个方向。
按时间重试
按次数重试
实现
Promie.retry
,成功后 resolve 结果,失败后重试,尝试超过一定次数才真正 reject1.2 任务中断
批量执行异步任务,有任务返回 false 就中断执行并返回结果。
1.3 异步竞态
认识竞态问题
竞态问题的出现的原因是无法保证异步操作的完成会按照他们开始时的顺序进行返回。下面的代码例子:
这就是一个常见的异步竞态的例子,在我们的投保流程中,测算在极端的情况下会碰到这种情况。
使用唯一 id 标识每次请求
封装指令式 promise