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

          es6-async await 手寫(xiě) 前端進(jìn)階必備

          共 4737字,需瀏覽 10分鐘

           ·

          2021-11-15 12:35

          雖然上次的表白計(jì)劃不了了之了,但我依然每天對(duì)她噓寒問(wèn)暖,我總相信,只要我對(duì)她好,總有一天我會(huì)感動(dòng)她的。我也開(kāi)始了所謂的舔狗之路......


          一次和她的聊天中知道她喜歡吃大后街的一家早餐,但每天都起不來(lái)。然后我提出幫她帶早餐,起初她還覺(jué)得有點(diǎn)不好意思稍稍有拒絕的意思,后來(lái)在我一系列勸說(shuō)下答應(yīng)了,她答應(yīng)的那一刻,我高興的像個(gè)孩子,那是我們除同學(xué)之外的第一個(gè)交集,也給我無(wú)限的遐想和期望。

          大后街還是有點(diǎn)遠(yuǎn)的,為了防止面條軟了,我也特意去買(mǎi)了輛自行車(chē),還記得第一次買(mǎi)早餐的時(shí)候,我給自己定了6點(diǎn)的鬧鐘,興奮、期待、緊張的我4點(diǎn)多就醒了,然后就毫無(wú)睡意了,腦子里一直在想等會(huì)應(yīng)該和她說(shuō)些啥,在哪里等她下來(lái).....

          給她帶早餐的第六天,她說(shuō)她來(lái)那個(gè)了,下來(lái)不了了,她的室友幫她下來(lái)拿的,那時(shí)候的我對(duì)這方面真的不懂,我們那的人感覺(jué)都太保守了,對(duì)這種東西比較隱晦,于是我百度了一下,然后叮囑她多喝紅糖水,多休息之類的話。聊著聊著我就懷著好奇問(wèn)了一下她:“這大姨媽一個(gè)月來(lái)幾次哇?”。這句話也讓我成為了大學(xué)班上四年的笑話,至今還被他們提起.....

          前言提示


          各位掘友們,此篇文章需要從頭認(rèn)真往下閱讀,不然無(wú)法理解下文我通過(guò)生成器*函數(shù)和yield實(shí)現(xiàn)的async awit。認(rèn)真閱讀包你搞透async 生成器 迭代器這些知識(shí)點(diǎn)。

          整理知識(shí)點(diǎn)不易,如果大家學(xué)到了,幫我點(diǎn)贊關(guān)注,后續(xù)我會(huì)繼續(xù)寫(xiě)進(jìn)階知識(shí)點(diǎn)。

          迭代器、生成器、async

          迭代器:迭代器是一種特殊對(duì)象,它具有一些專門(mén)為迭代過(guò)程設(shè)計(jì)的專有接口,所有的迭代器對(duì)象都有一個(gè)next()方法,每次調(diào)用都返回一個(gè)結(jié)果對(duì)象。結(jié)果對(duì)象有兩個(gè)屬性:一個(gè)是value,表示下一個(gè)將要返回的值;另一個(gè)是done,它是一個(gè)布爾類型的值,當(dāng)沒(méi)有更多可返回?cái)?shù)據(jù)時(shí)返回true。迭代器還會(huì)保存一個(gè)內(nèi)部指針,用來(lái)指向當(dāng)前集合中值的位置,每調(diào)用一次next()方法,都會(huì)返回下一個(gè)可用的值

          如何區(qū)分是否能迭代
             let arr=[1,2,3]     let str='123'     let obj={a:1,b:2}
          for(var i of arr){ console.log('數(shù)組',i) }
          for(var i of str){ console.log('字符串',i) }
          for(var i of obj){ console.log('對(duì)象',i) }

          打印結(jié)果如下圖

          說(shuō)明:對(duì)象是不可迭代的

          可以從原型去看一個(gè)類型是否支持迭代,以字符串為例

          展開(kāi)字符串的原型,會(huì)發(fā)現(xiàn)它存在Symbol(Symbol.iterator)這個(gè)屬性,說(shuō)明它是可以迭代的。

          把這個(gè)屬性用起來(lái),再結(jié)合迭代器的描述,你或許能進(jìn)一步理解迭代器。?
          以?
          let str1='舔狗的淚'?為例

          手動(dòng)實(shí)現(xiàn)一個(gè)迭代器效果 ? 以對(duì)象為例

           var obj = {      a: 1,      b: 2,      c: 3,      [Symbol.iterator]() {        var index = 0;        let map = new Map([          ["a", 1],          ["b", 2],          ["c", 3],        ]);        return {          next() {            let mapEntries = [...map.entries()];//將它還原成二維數(shù)組            if (index < map.size) {              return {                value: mapEntries[index++],                done: false,              };            } else {              return { value: undefined, done: true };            }          },        };      },    };    let iter=obj[Symbol.iterator]()

          測(cè)試下,同時(shí)會(huì)發(fā)現(xiàn)這個(gè)對(duì)象是能支持for of 的

          遍歷和迭代的區(qū)別

          迭代:從目標(biāo)源依次逐個(gè)抽取的方式來(lái)提取數(shù)據(jù)。目標(biāo)源是有序,連續(xù)
          遍歷:只要能夠循環(huán)數(shù)據(jù),并不需要有序。
          因?yàn)閷?duì)象循環(huán)不是有序的,所有它無(wú)法迭代,但是Map是可以支持迭代的。

          生成器

          函數(shù)前帶 * 表示生成器 ?用yield去產(chǎn)出它的值

          function * test(){      yield 1      yield 2      yield 3    }  var iter=test()  iter.next()  //輸出 {value:1,done:false}
          iter也是可以通過(guò)for of循環(huán),這里不演示了

          注意:每次調(diào)用next,他都會(huì)走到一個(gè)yield,下面代碼不會(huì)打印log

            function * test(){      console.log('舔狗的淚')      yield 1      yield 2      yield 3    }  var iter=test()  //要調(diào)用iter.next()才會(huì)走console.log
          生成器的yield 換成return 看看區(qū)別:


          基于yield去改造剛才讓對(duì)象能夠迭代的方法
          var?obj?=?{        a: 1,        b: 2,        c: 3,        [Symbol.iterator]:function * () {          var index = 0;          let map = new Map([            ['a', 1],            ['b', 2],            ['c', 3]          ]);          let mapEntries = [...map.entries()]; //將它還原成二維數(shù)組          while(index            yield mapEntries[index++]          }        }      };      let iter = obj[Symbol.iterator]();
          對(duì)next方法傳參,看看yield丑陋的一面,async前世
            function* test() {        let value1 = yield 1;        console.log('value1',value1);        let value2 = yield 2;        console.log('value2',value2);        let value3 = yield 3;        console.log('value3',value3);      }      var iter=test()      iter.next('one')      iter.next('two')      iter.next('three')      iter.next('')

          結(jié)果分析:next里面的值會(huì)賦給上一次yield 的值 。
          站在開(kāi)發(fā)者角度更期望 value1 打印的值就是1。async await它來(lái)了


          async await基本操作

          async await常見(jiàn)用法:let x=await 異步請(qǐng)求
          看看它的其他用法,直接看圖說(shuō)話:

            function b() {        return new Promise(resolve => {          setTimeout(() => resolve(1), 1000);        });      }      async function a() {        let value = await b();        console.log(value);      }      a();      //1秒后打印1
             function b(){        return 1      }      async function a() {        let value = await b();        console.log(value);      }      a();      //打印1
          function b() {        let c = 1;      }      async function a() {        let a = await b();        console.log(a);      }      a();       //打印undefined

          基于* yield實(shí)現(xiàn)一個(gè)async

          以下面例子去實(shí)現(xiàn)

          let num=1      //b函數(shù)只為模擬一個(gè)axios      function b() {        return new Promise(resolve => {          setTimeout(() => resolve(num++), 1000);        });      }      async function a() {        let value1 = await b();        let value2 = await b();        let value3 = await b();        console.log(value1,value2,value3);        return value3      }      let promise =a();      //3秒后打印 1,2,3
          基于生成器 遞歸實(shí)現(xiàn),需要先看上面的對(duì)next方法傳參,你才能明白下圖
           let num = 1;      function b() {        return new Promise(resolve => {          setTimeout(() => resolve(num++), 1000);        });      }      function* a() {        let value1 = yield b();        let value2 = yield b();        let value3 = yield b();        console.log(value1, value2, value3);        return value3      }      function Co(iter) {      //因?yàn)閍sync方法內(nèi)部包裹的就是Promise,所以這里也return一個(gè)Promise        return new Promise((resolve, reject) => {          let next = function (data) {            let { value, done } = iter.next(data);            if (done) {              resolve(data);            } else {            //兼容b函數(shù)是一個(gè)非異步操作            value instanceof Promise?              value.then(val => {                next(val);              }, reject):next(value);            }          };          next();        });      }     let promise = Co(a());
          個(gè)人理解及總結(jié)

          迭代器:它的原型上面存在Symbol(Symbol.iterator),它可以被for of 循環(huán)
          生成器:* 配合yield 的一個(gè)函數(shù)
          如果你搞懂了生成器函數(shù),基于它實(shí)現(xiàn)async await就變得很容易了。
          目前把es6里面的class Map Set Promise底層實(shí)現(xiàn)都寫(xiě)完了

          源自:https://juejin.cn/post/7029100142208745503

          聲明:文章著作權(quán)歸作者所有,如有侵權(quán),請(qǐng)聯(lián)系小編刪除。

          感謝 · 轉(zhuǎn)發(fā)歡迎大家留言


          瀏覽 47
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <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>
                  日本欧美成人片AAAA | 欧美成人久久 | 国产老妇乱伦 | 日韩三级片电影网站 | 欧美日韩亚洲另类 |