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

        共 4737字,需瀏覽 10分鐘

         ·

        2021-11-15 12:35

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


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

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

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

        前言提示


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

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

        迭代器、生成器、async

        迭代器:迭代器是一種特殊對(duì)象,它具有一些專門為迭代過程設(shè)計(jì)的專有接口,所有的迭代器對(duì)象都有一個(gè)next()方法,每次調(diào)用都返回一個(gè)結(jié)果對(duì)象。結(jié)果對(duì)象有兩個(gè)屬性:一個(gè)是value,表示下一個(gè)將要返回的值;另一個(gè)是done,它是一個(gè)布爾類型的值,當(dāng)沒有更多可返回?cái)?shù)據(jù)時(shí)返回true。迭代器還會(huì)保存一個(gè)內(nè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é)果如下圖

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

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

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

        把這個(gè)屬性用起來,再結(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]()

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

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

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

        生成器

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

        function * test(){      yield 1      yield 2      yield 3    }  var iter=test()  iter.next()  //輸出 {value:1,done:false}
        iter也是可以通過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 的值 。
        站在開發(fā)者角度更期望 value1 打印的值就是1。async await它來了


        async await基本操作

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

          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)都寫完了

        源自: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)
          
          

            1. 乱淫男女小说 | av好大在线观看网站先看字幕 | 日韩AAA视频 | 暴力操逼 | 91蜜桃婷婷狠狠久久综合9色 |