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

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

          共 4179字,需瀏覽 9分鐘

           ·

          2021-04-11 23:09

          點擊上方 三分鐘學前端,關(guān)注公眾號

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

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

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

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

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

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

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

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

          2. Promise

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

          Promise 實現(xiàn)了鏈式調(diào)用,也就是說每次 then 后返回的都是一個全新 Promise,如果我們在 then 中 return ,return 的結(jié)果會被 Promise.resolve() 包裝

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

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

          缺點:無法取消 Promise ,錯誤需要通過回調(diào)函數(shù)來捕獲

          3. Generator

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

          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)點是:代碼清晰,不用像 Promise 寫一大堆 then 鏈,處理了回調(diào)地獄的問題

          缺點:await 將異步代碼改造成同步代碼,如果多個異步操作沒有依賴性而使用 await 會導致性能上的降低。

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

          下面來看一個使用 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

          對于以上代碼你可能會有疑惑,讓我來解釋下原因

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

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

          二、4 種方式實現(xiàn)一個 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);

          來自:https://github.com/sisterAn/blog

          最后

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

          手機掃一掃分享

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

          手機掃一掃分享

          分享
          舉報
          <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>
                  精品国产a∨一区天美传媒 | 最新日韩免费在线 | 91精品少妇高潮一区二区三区不卡 | 亚洲视频网站免费 | 亚洲色图在线观看视频 |