1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        看一道面試必備的基礎(chǔ)題:異步實(shí)現(xiàn)一個(gè) sleep 函數(shù)

        共 4179字,需瀏覽 9分鐘

         ·

        2021-04-17 07:05

        點(diǎn)擊上方 三分鐘學(xué)前端,關(guān)注公眾號(hào)

        面試官也在看的前端面試資料

        一、JS異步解決方案的發(fā)展歷程以及優(yōu)缺點(diǎn)

        1. 回調(diào)函數(shù)(callback)

        setTimeout(() => {
            // callback 函數(shù)體
        }, 1000)

        缺點(diǎn):回調(diào)地獄,不能用 try catch 捕獲錯(cuò)誤,不能 return

        回調(diào)地獄的根本問(wèn)題在于:

        • 缺乏順序性:回調(diào)地獄導(dǎo)致的調(diào)試?yán)щy,和大腦的思維方式不符
        • 嵌套函數(shù)存在耦合性,一旦有所改動(dòng),就會(huì)牽一發(fā)而動(dòng)全身,即(控制反轉(zhuǎn)
        • 嵌套函數(shù)過(guò)多的多話(huà),很難處理錯(cuò)誤
        ajax('XXX1', () => {
            // callback 函數(shù)體
            ajax('XXX2', () => {
                // callback 函數(shù)體
                ajax('XXX3', () => {
                    // callback 函數(shù)體
                })
            })
        })

        優(yōu)點(diǎn):解決了同步的問(wèn)題(只要有一個(gè)任務(wù)耗時(shí)很長(zhǎng),后面的任務(wù)都必須排隊(duì)等著,會(huì)拖延整個(gè)程序的執(zhí)行。)

        2. Promise

        Promise就是為了解決callback的問(wèn)題而產(chǎn)生的。

        Promise 實(shí)現(xiàn)了鏈?zhǔn)秸{(diào)用,也就是說(shuō)每次 then 后返回的都是一個(gè)全新 Promise,如果我們?cè)?then 中 return ,return 的結(jié)果會(huì)被 Promise.resolve() 包裝

        優(yōu)點(diǎn):解決了回調(diào)地獄的問(wèn)題

        ajax('XXX1')
          .then(res => {
              // 操作邏輯
              return ajax('XXX2')
          }).then(res => {
              // 操作邏輯
              return ajax('XXX3')
          }).then(res => {
              // 操作邏輯
          })

        缺點(diǎn):無(wú)法取消 Promise ,錯(cuò)誤需要通過(guò)回調(diào)函數(shù)來(lái)捕獲

        3. Generator

        特點(diǎn):可以控制函數(shù)的執(zhí)行,可以配合 co 函數(shù)庫(kù)使用

        function *fetch({
            yield ajax('XXX1', () => {})
            yield ajax('XXX2', () => {})
            yield ajax('XXX3', () => {})
        }
        let it = fetch()
        let result1 = it.next()
        let result2 = it.next()
        let result3 = it.next()

        4. Async/await

        async、await 是異步的終極解決方案

        優(yōu)點(diǎn)是:代碼清晰,不用像 Promise 寫(xiě)一大堆 then 鏈,處理了回調(diào)地獄的問(wèn)題

        缺點(diǎn):await 將異步代碼改造成同步代碼,如果多個(gè)異步操作沒(méi)有依賴(lài)性而使用 await 會(huì)導(dǎo)致性能上的降低。

        async function test({
          // 以下代碼沒(méi)有依賴(lài)性的話(huà),完全可以使用 Promise.all 的方式
          // 如果有依賴(lài)性的話(huà),其實(shí)就是解決回調(diào)地獄的例子了
          await fetch('XXX1')
          await fetch('XXX2')
          await fetch('XXX3')
        }

        下面來(lái)看一個(gè)使用 await 的例子:

        let a = 0
        let b = async () => {
          a = a + await 10
          console.log('2', a) // -> '2' 10
        }
        b()
        a++
        console.log('1', a) // -> '1' 1

        對(duì)于以上代碼你可能會(huì)有疑惑,讓我來(lái)解釋下原因

        • 首先函數(shù) b 先執(zhí)行,在執(zhí)行到 await 10 之前變量 a 還是 0,因?yàn)?await 內(nèi)部實(shí)現(xiàn)了 generatorgenerator 會(huì)保留堆棧中東西,所以這時(shí)候 a = 0 被保存了下來(lái)
        • 因?yàn)?await 是異步操作,后來(lái)的表達(dá)式不返回 Promise 的話(huà),就會(huì)包裝成 Promise.reslove(返回值),然后會(huì)去執(zhí)行函數(shù)外的同步代碼
        • 同步代碼執(zhí)行完畢后開(kāi)始執(zhí)行異步代碼,將保存下來(lái)的值拿出來(lái)使用,這時(shí)候 a = 0 + 10

        上述解釋中提到了 await 內(nèi)部實(shí)現(xiàn)了 generator,其實(shí) await 就是 generator 加上 Promise的語(yǔ)法糖,且內(nèi)部實(shí)現(xiàn)了自動(dòng)執(zhí)行 generator。如果你熟悉 co 的話(huà),其實(shí)自己就可以實(shí)現(xiàn)這樣的語(yǔ)法糖。

        二、4 種方式實(shí)現(xiàn)一個(gè) sleep 函數(shù)

        1. Promise

        //Promise
        const sleep = time => {
          return new Promise(resolve => setTimeout(resolve,time))
        }
        sleep(1000).then(()=>{
          console.log(1)
        })

        2. Generator

        //Generator
        functionsleepGenerator(time{
          yield new Promise(function(resolve,reject){
            setTimeout(resolve,time);
          })
        }
        sleepGenerator(1000).next().value.then(()=>{console.log(1)})

        3. async await

        //async
        function sleep(time{
          return new Promise(resolve => setTimeout(resolve,time))
        }
        async function output({
          let out = await sleep(1000);
          console.log(1);
          return out;
        }
        output();

        4. ES5

        //ES5
        function sleep(callback,time{
          if(typeof callback === 'function')
            setTimeout(callback,time)
        }

        function output(){
          console.log(1);
        }
        sleep(output,1000);

        來(lái)自:https://github.com/sisterAn/blog

        最后

        歡迎關(guān)注「三分鐘學(xué)前端」,回復(fù)「交流」自動(dòng)加入前端三分鐘進(jìn)階群,每日一道編程算法面試題(含解答),助力你成為更優(yōu)秀的前端開(kāi)發(fā)!
        》》面試官也在看的前端面試資料《《
        “在看和轉(zhuǎn)發(fā)”就是最大的支持
        瀏覽 79
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

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

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            欧美日韩操逼网 | AV网站在线免费观看 | 手机在线看片国产在线观看一区二区 | 久久人人爽人人爽人人片av不 | 制服丝袜第二页 | 乱伦视频综合网 | 伊人操逼 | 大学生高潮一级毛片免费视频 | 亚洲乱伦另类 | 在线观看欧美另类色图365 |