<!DOCTYPE html>
<html>
<head>
<title>异步的传染性问题</title>
<script type="text/javascript">
function A(){
console.log('======= 异步的传染性问题 =======');
async function getUser() {
return await fetch('./test.json').then(r=>r.json());
}
async function m1() { return await getUser(); }
async function m2() { return await m1(); }
async function m3() { return await m2(); }
async function main() {
const user = await m3();
console.log('[A] main(): user = ', user);
}
main();
}
// A();
</script>
<script type="text/javascript">
function B(){
console.log('======= 全部函数改为同步 =======');
function getUser() { return fetch('./test.json'); }
function m1() { const user = getUser(); return user; }
function m2() { const user = m1(); return user; }
function m3() { const user = m2(); return user; }
function main() { const user = m3(); console.log('main execute -> user:', user); }
function run(func) {
// 1. 保存旧的 fetch
const rawFetch = window.fetch;
// 2. 重写fetch
const cache = {
status: 'pending', // pending, fulfilled, rejected
value: null
};
// 2. 重写 fetch
const newFetch = (...args) => {
// 有缓存,交付缓存
if (cache.status === 'fulfilled') {
return cache.value;
} else if (cache.status === 'rejected') {
throw cache.value;
}
const p = rawFetch(...args)
.then((res)=>res.json())
.then((data)=>{
cache.status = 'fulfilled';
cache.value = data;
});
// 2. 抛出错误,中断执行
throw p;
}
window.fetch = newFetch;
// 3. 执行函数
try {
// 执行 func() 即 main(), 此时 main 里的 fetch 是 newFetch.
func();
}
catch (err) {
// 判断 err 是不是 throw p 返回的Promise类型, 是则执行 func();
if (err instanceof Promise) {
// 在 err 这个Promse 执行到最后时, 说明 getUser里的fetch 已经异步获取到了 json数据,
// 此时再次执行 func(); 获取数据;
err.finally(() => {
window.fetch = newFetch;
func();
window.fetch = rawFetch;
});
}
}
// 4. 恢复 fetch
window.fetch = rawFetch;
// 5. 返回结果
return func();
}
// main 会执行二次
// 第一次: 执行fetch, 异步发出; main execute -> user: Promise(正在执行的异步请求)
// 第二次: err.finally(()=>{ ...; func(); ... }) 获取到异步返回的数据. main execute -> user: 异步返回的json数据
run(main);
}
B();
</script>
</head>
<body>
</body>
</html>