<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          異步無處不在:Generator 異步(五)

          共 3210字,需瀏覽 7分鐘

           ·

          2021-01-15 18:40

          (????)??嗨,我是你穩(wěn)定更新、持續(xù)輸出的勾勾。



          關(guān)于異步的知識點,終于要結(jié)束了!


          本篇就來重點說說如何將 Generator 寫進(jìn)異步中


          Generator 異步方案


          將調(diào)用 ajax 的代碼寫到生成器函數(shù)的 yield 后面,每次的異步執(zhí)行,都要在 yield 中暫停,調(diào)用的返回結(jié)果是一個 Promise 對象。


          我們可以從迭代器對象的 value 屬性獲取到 Promise 對象,然后使用 .then 進(jìn)行鏈?zhǔn)秸{(diào)用處理異步結(jié)果。


          結(jié)果處理的代碼叫做執(zhí)行器,就是具體負(fù)責(zé)運(yùn)行邏輯的代碼。

          function ajax(url) {    ……}
          // 聲明一個生成器函數(shù)function * fun(){ yield myAjax('./d1.json') yield myAjax('./d2.json') yield myAjax('./d3.json')}
          // 返回 遍歷器對象 var f = fun();// 生成器函數(shù)的執(zhí)行器 // 調(diào)用 next 方法,執(zhí)行異步代碼var g = f.next();g.value.then(data=>{ console.log(data); // console.log(f.next()); g = f.next(); g.value.then(data=>{ console.log(data) // g....... })})


          而執(zhí)行器的邏輯中,是相同嵌套的,因此可以寫成遞歸的方式對執(zhí)行器進(jìn)行改造:

          //?聲明一個生成器函數(shù)function * fun(){    yield myAjax('./d1.json')    yield myAjax('./d2.json')    yield myAjax('./d3.json')}
          // 返回 遍歷器對象 var f = fun();// 遞歸方式 封裝// 生成器函數(shù)的執(zhí)行器function handle(res){ if(res.done) return; res.value.then(data=>{ console.log(data) handle(f.next()) })}handle(f.next());


          然后,再將執(zhí)行的邏輯,進(jìn)行封裝復(fù)用,形成獨(dú)立的函數(shù)模塊。

          function co(fun) {    // 返回 遍歷器對象     var f = fun();    // 遞歸方式 封裝    // 生成器函數(shù)的執(zhí)行器    function handle(res) {        if (res.done) return;        res.value.then(data => {            console.log(data)            handle(f.next())        })    }    handle(f.next());}
          co(fun);


          封裝完成后,我們再使用時只需要關(guān)注 Generator 中的 yield 部分就行了。

          function co(fun) {    ……}
          function * fun(){ yield myAjax('./d1.json') yield myAjax('./d2.json') yield myAjax('./d3.json')}


          此時你會發(fā)現(xiàn),使用 Generator 封裝后,異步的調(diào)用就變得非常簡單了。


          但是,這個封裝還是有點麻煩,有大神幫我們做了這個封裝,相當(dāng)強(qiáng)大:https://github.com/tj/co ,感興趣可以研究一下。


          而隨著 JS 語言的發(fā)展,更多的人希望類似 co 模塊的封裝能夠?qū)戇M(jìn)語言標(biāo)準(zhǔn)中,而我們直接使用這個語法規(guī)則就行了。


          其實你也可以對比一下,使用 co 模塊后的 Generator 和 async 這兩段代碼:

          //  async / await async function callAjax(){     var a = await myAjax('./d1.json')     console.log(a);     var b = await myAjax('./d2.json');     console.log(b)     var c = await myAjax('./d3.json');     console.log(c) }  // 使用 co 模塊后的 Generator function * fun(){    yield myAjax('./d1.json')    yield myAjax('./d2.json')    yield myAjax('./d3.json')}


          你應(yīng)該也發(fā)現(xiàn)了,async 函數(shù)就是 Generator 語法糖,不需要自己再去實現(xiàn) co 執(zhí)行器函數(shù)或者安裝 co 模塊。


          寫法上將 * 星號去掉換成放在函數(shù)前面的 async,把函數(shù)體的 yield 去掉,換成 await。


          簡直完美!


          async function callAjax(){     var a = await myAjax('./d1.json')     console.log(a);     var b = await myAjax('./d2.json');     console.log(b)     var c = await myAjax('./d3.json');     console.log(c) }callAjax();


          我們再來看一下 Generator。


          相信下面的代碼,你能很輕松地閱讀。

          function * f1(){    console.log(11)    yield 2;    console.log('333')    yield 4;    console.log('555')}
          var g = f1();g.next();console.log(666);g.next();console.log(777);


          代碼運(yùn)行結(jié)果:



          帶著 Generator ?的思路,我們再回頭看看那個 async 的面試題。


          請寫出以下代碼的運(yùn)行結(jié)果:

          setTimeout(function () {    console.log('setTimeout')}, 0)
          async function async1() { console.log('async1 start') await async2(); console.log('async1 end')}
          async function async2() { console.log('async2')}
          console.log('script start')
          async1();
          console.log('script end')


          運(yùn)行結(jié)果:



          是不是恍然大明白呢(●'?'●)。


          推薦閱讀:

          異步無處不在:同步模式和異步模式(一)

          異步無處不在:回調(diào)函數(shù)(二)

          異步無處不在:Promise 破除“回調(diào)地獄”(三)

          異步無處不在:終極解決方案(四)

          Redux 續(xù)集 | 如何搞定其中的異步操作?

          技術(shù)人年度總結(jié) | 2020,注定不平凡

          是我 Web 端配不上阿里了。

          前端人因為 Vue3 的 Ref-sugar 提案打起來了!


          點點“”和“在看”,保護(hù)頭發(fā),減少bug。

          瀏覽 21
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  日本欧美三级 | 北条麻妃91视频 | 无套内射学生妹 | 成人精品一区二区婷婷 | 国产一级二级三级在线观看 |