异步的传染性问题

<!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>

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

友情链接更多精彩内容