异步传染性
2023年12月29日
一、认识
function request() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve('done');
}, 1000);
});
}
async function foo1(){
let result = await request();
return result;
}
async function foo2(){
let result = await foo1();
return result;
}
async function run(){
let result = await foo2();
return result;
}
如上所示, request
是异步的, 导致了 foo1
、foo2
、run
变成了 async function
。类似这样的现象叫做异步传染性
二、消除
什么是消除异步传染性呢? 就是希望 foo1
、foo2
、run
不要加入 async/await
, 变成纯函数调用, 实现如下:
function request(url, ...args) {
return new Promise((resolve, reject) => {
setTimeout(() => {
console.log('url', url);
resolve('done');
}, 1000);
});
}
function foo1() {
let result = request('http://www.baidu.com', 1, 2, 3);
return result;
}
function foo2() {
let result = foo1();
return result;
}
function main() {
let result = foo2();
console.log(result);
}
function runMain(main) {
const promiseMap = new Map();
const originRequest = request;
request = function (url, ...args) {
const mapKey = url + JSON.stringify(args);
if (promiseMap.has(mapKey)) {
const promise = promiseMap.get(mapKey);
if (promise.state === 'fulfilled') {
return promise.result;
} else if (promise.state === 'rejected') {
throw promise.error;
}
} else {
let curr = originRequest(url, ...args)
.then(res => {
promiseMap.set(mapKey, {
state: 'fulfilled',
result: res
});
})
.catch(error => {
promiseMap.set(mapKey, {
state: 'rejected',
error: error
});
});
throw curr;
}
};
try {
main();
} catch (error) {
if (error instanceof Promise) {
error.then(main, main).finally(() => (request = originRequest));
}
}
}
runMain(main);