在开发的过程中可能会遇到代码中包含复杂异步函数, 若返回结果相同或一定时间内返回结果相同. 可以使用如下写法来避免对于该复杂异步函数的重复执行.
// 重复执行复杂异步函数
const complexAsyncFn = () => new Promise((resolve) => {
setTimeout(() => {
const year = new Date().getFullYear();
console.log(`complexAsyncFn: ${year}`)
resolve(year);
}, Math.round(Math.random() * 4096));
})
setTimeout(async() => {
const year = await complexAsyncFn();
console.log(`q1: ${year}`)
}, Math.round(Math.random() * 1024));
setTimeout(async() => {
const year = await complexAsyncFn();
console.log(`q2: ${year}`)
}, Math.round(Math.random() * 1024));
setTimeout(async() => {
const year = await complexAsyncFn();
console.log(`q3: ${year}`)
}, Math.round(Math.random() * 1024));
setTimeout(async() => {
const year = await complexAsyncFn();
console.log(`q4: ${year}`)
}, Math.round(Math.random() * 1024));
/*
=> complexAsyncFn: 2022
=> q3: 2022
=> complexAsyncFn: 2022
=> q1: 2022
=> complexAsyncFn: 2022
=> q2: 2022
=> complexAsyncFn: 2022
=> q4: 2022
*/
// complexAsyncFn 被执行了3次
// 避免重复执行复杂异步函数
const complexAsyncFn = () => new Promise((resolve) => {
setTimeout(() => {
const year = new Date().getFullYear();
console.log(`complexAsyncFn: ${year}`)
resolve(year);
}, Math.round(Math.random() * 4096));
})
let answer = undefined;
const listeners = [];
const messenger = () => new Promise((resolve) => {
if (answer !== undefined) { return resolve(answer); }
listeners.push(resolve);
if (listeners.length === 1) {
complexAsyncFn().then((result) => {
answer = result;
listeners.forEach((listener) => listener(result));
listeners.length = 0
});
}
});
setTimeout(async() => {
const year = await messenger();
console.log(`q1: ${year}`, new Date().getTime())
}, Math.round(Math.random() * 1024));
setTimeout(async() => {
const year = await messenger();
console.log(`q2: ${year}`, new Date().getTime())
}, Math.round(Math.random() * 1024));
setTimeout(async() => {
const year = await messenger();
console.log(`q3: ${year}`, new Date().getTime())
}, Math.round(Math.random() * 1024));
setTimeout(async() => {
const year = await messenger();
console.log(`q4: ${year}`, new Date().getTime())
}, Math.round(Math.random() * 1024 + 4096));
/*
=> complexAsyncFn: 2022
=> q1: 2022 1658819426219
=> q2: 2022 1658819426219
=> q3: 2022 1658819426219
=> q4: 2022 1658819427634
*/
// complexAsyncFn 被执行了1次, q1, q2, q3 同时获得了结果, q4 直接获得了结果