背景
我们在开发过程中都知道,如果要使用async 和 await 语法糖必须在函数使用的链路上全部都要使用async 和 await, 不够优雅,那么有什么办法可以消除异步的传染性呢?
常见使用方式
const getdata = async () => {
const res = await fetch(url).then( response=>console.log(response))
}
const fn1 = async () => {
await getdata()
}
const fn2 = async () => {
await fn1()
}
const fn3 = async () => {
await fn2()
}
fn3()
消除异步传染性
那么如何消除异步的传染性呢? 思路: 很明显必须在源头进行处理, 否则在链路的任意一环处理都不可能消除, 那么如何处理呢? 在请求的时候会有延迟,那么只有将异步的动作同步化,然后增加缓存才能解决异步的传染性, 也就是使用抛出异常的方式来解决该问题
function getdata() {
return fetch('./data.json');
}
function m1() {
return getdata();
}
function m2() {
return m1();
}
function m3() {
return m2();
}
function main() {
const data = m3();
console.log(data);
}
function eliAsync(func) {
let cache = [];
let i = 0;
const _originalFetch = window.fetch;
window.fetch = (...args) => {
if(cache[i]) {
if(cache[i].status === 'fulfilled') {
return cache[i].data;
} else if(cache[i].status === 'rejected') {
throw cache[i].err;
}
}
const result = {
status: 'pending',
data: null,
err: null
};
cache[i++] = result;
const prom = _originalFetch(...args).then(resp => resp.json()).then(res => {
result.status = 'fulfilled';
result.data = res;
}, err => {
reslut.status = 'rejected';
result.err = err;
});
throw prom;
}
try {
func();
} catch(err) {
if(err instanceof Promise) {
const reRun = () => {
i = 0;
func();
}
err.then(reRun, reRun);
}
}
};
eliAsync(fn3);