日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[面试题]事件循环经典面试题解析

發(fā)布時間:2023/12/9 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [面试题]事件循环经典面试题解析 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

Python微信訂餐小程序課程視頻

https://edu.csdn.net/course/detail/36074

Python實戰(zhàn)量化交易理財系統(tǒng)

https://edu.csdn.net/course/detail/35475

基礎概念

  • 進程是計算機已經運行的程序,線程是操作系統(tǒng)能夠進行運算調度的最小單位,它被包含在進程中.瀏覽器中每開一個Tab頁,就會打開一個進程,而這個進程又包含了很多線程.
  • 大家都知道JS是一門單線程語言,如果遇到了非常耗時的操作,那么JS的執(zhí)行就會受到阻塞,這肯定不是我們想看到的,所以這些耗時的操作,往往不是由JS線程所執(zhí)行的,而是交由瀏覽器中的其他線程去完成的,成功之后只要在某個特定的時候進行一個回調函數即可
  • 所以引出了事件循環(huán)的概念,在事件循環(huán)中,分兩種任務,分別是宏任務和微任務
  • 宏任務包含 ajax、setTimeout、setInterval、DOM監(jiān)聽、UI Rendering
  • 微任務包含 Promise的then回調、 Mutation Observer API、queueMicrotask()等
  • 接下來我們直接就開始練習面試題熟悉熟悉
  • 面試題一

    復制代碼
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    javascript`setTimeout(function () {
    console.log(“setTimeout1”);

    new Promise(function (resolve) {
    resolve();
    }).then(function () {
    new Promise(function (resolve) {
    resolve();
    }).then(function () {
    console.log(“then4”);
    });
    console.log(“then2”);
    });
    });

    new Promise(function (resolve) {
    console.log(“promise1”);
    resolve();
    }).then(function () {
    console.log(“then1”);
    });

    setTimeout(function () {
    console.log(“setTimeout2”);
    });

    console.log(2);

    queueMicrotask(() => {
    console.log(“queueMicrotask1”)
    });

    new Promise(function (resolve) {
    resolve();
    }).then(function () {
    console.log(“then3”);
    });`

  • 先解決同步任務
  • 輸出promise1 2
  • 開始解決異步任務中的微任務
  • 輸出then1 queueMicrotask1 then3
  • 開始解決異步任務中的宏任務
  • 輸出setTimeout1,在第一個定時器中,又遇到了微任務,那么接著執(zhí)行微任務
  • 輸出then2 然后輸出 then4
  • 目光跳出第一個定時器中,看到第二個定時器 開始輸出setTimeout2
  • 最后的完整輸出為 promise1 2 then1 queueMicrotask1 then3 setTimeout1 then2 then4 setTimeout2
  • 面試題二

    復制代碼
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    javascript`async function async1() {
    console.log(‘async1 start’)
    // await異步函數的返回結果 resolve的結果會作為整個異步函數的promise的resolve結果->同步代碼
    // await后面的執(zhí)行代碼 就會變成.then后面的執(zhí)行函數->微任務
    // 也就是說 console.log(‘async1 end’) 這一段是相當于then方法內的 會被加入微任務中
    await async2();
    console.log(‘async1 end’)
    }

    async function async2() {
    console.log(‘async2’)
    }

    console.log(‘script start’)

    setTimeout(function () {
    console.log(‘setTimeout’)
    }, 0)

    async1();

    new Promise(function (resolve) {
    console.log(‘promise1’)
    resolve();
    }).then(function () {
    console.log(‘promise2’)
    })

    console.log(‘script end’)`

  • 先執(zhí)行同步代碼
  • 輸出script start async1 start async2 promise1 script end
  • 開始執(zhí)行微任務
  • 輸出async1 end promise2
  • 最后執(zhí)行宏任務
  • 輸出setTimeout
  • 完整輸出:script start async1 start async2 promise1 script end async1 end promise2 setTimeout
  • 面試題三

    復制代碼
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    javascript`Promise.resolve().then(() => {
    console.log(0);
    //1.直接返回4 微任務不會做任何延遲
    // return 4
    //2.直接返回Promise.resolve(4) 微任務推遲兩次
    // return Promise.resolve(4);
    //3.返回thenable對象
    return {
    then: ((resolve, reject) => {
    resolve(4);
    })
    }
    }).then((res) => {
    console.log(res)
    })

    Promise.resolve().then(() => {
    console.log(1);
    }).then(() => {
    console.log(2);
    }).then(() => {
    console.log(3);
    }).then(() => {
    console.log(5);
    }).then(() => {
    console.log(6);
    })`
    這道面試題有些特殊,需要大家記住兩個結論

  • 如果返回的是thenable對象,那么微任務會推遲一次,thenable對象就是實現(xiàn)了Promise.then的那個函數,具體可看代碼
  • 如果返回的是Promise.resolve(4),那么微任務會推遲兩次,這個相當于是返回一個Promise之后又用了resolve,二者是等價的
  • 為了配合大家理解,我給大家畫了幾張圖,大家可以看看
  • [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-aMWrhIg9-1646846037009)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/569c204f981e42c5a98d2014e4594856~tplv-k3u1fbpfcp-zoom-1.image “上述是then中返回的三種情況”)]
    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-itzZizEq-1646846037013)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6e5976aafab541deace1e7dfdfa55ae6~tplv-k3u1fbpfcp-zoom-1.image “普通返回,不會推遲”)][外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-YB6D2Rjk-1646846037014)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6d76aecd1449480ab33d9ffa352ff3e2~tplv-k3u1fbpfcp-zoom-1.image “返回thenable 推遲一次”)][外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-TxUzboTl-1646846037015)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/9446c84c4a4846deb833e0b2597642fd~tplv-k3u1fbpfcp-zoom-1.image “返回Promise.resolve,推遲兩次”)]

    面試題四

    本道題是基于node的事件循環(huán),和瀏覽器的事件循環(huán)不一樣,需要記住以下幾點

    node的事件循環(huán)也分宏任務和微任務

    • 宏任務: setTimeout、setInterval、IO事件、setImmediate、close事件
    • 微任務: Promise的then回調、process.nextTick、queueMicrotask

    node的每次事件循環(huán)都是按照以下順序來執(zhí)行的

  • next tick microtask queue
  • other microtask queue
  • timer queue
  • poll queue
  • pcheck queue
  • close queue
  • 復制代碼
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    javascript`async function async1() {
    console.log(‘async1 start’)
    await async2()
    console.log(‘async1 end’)
    }

    async function async2() {
    console.log(‘async2’)
    }

    console.log(‘script start’)

    setTimeout(function () {
    console.log(‘setTimeout0’)
    }, 0)

    setTimeout(function () {
    console.log(‘setTimeout2’)
    }, 300)

    setImmediate(() => console.log(‘setImmediate’));

    process.nextTick(() => console.log(‘nextTick1’));

    async1();

    process.nextTick(() => console.log(‘nextTick2’));

    new Promise(function (resolve) {
    console.log(‘promise1’)
    resolve();
    console.log(‘promise2’)
    }).then(function () {
    console.log(‘promise3’)
    })

    console.log(‘script end’)`

  • 首先執(zhí)行同步任務
  • 輸出script start async1 start async2 promise1 promise2 script end
  • 接著執(zhí)行微任務,因為node會優(yōu)先執(zhí)行nextTick這個微任務
  • 所以先輸出nextTick1 nextTick2
  • 在輸出其他微任務,輸出async1 end promise3
  • 最后執(zhí)行宏任務
  • 輸出 setTimeout0 setImmediate
  • 因為這個定時器延時3ms執(zhí)行,所以會讓其他的宏任務先執(zhí)行完畢,才回去執(zhí)行這個定時器,所以最后輸出setTimeout2
  • 最后的輸出結果: script start async1 start async2 promise1 promise2 script end nextTick1 nextTick2 async1 end promise3 setTimeout0 setImmediate setTimeout2
  • 總結

    以上是生活随笔為你收集整理的[面试题]事件循环经典面试题解析的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。