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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

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

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

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

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

Python實(shí)戰(zhàn)量化交易理財(cái)系統(tǒng)

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

基礎(chǔ)概念

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

    復(fù)制代碼
    • 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”);
    });`

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

    復(fù)制代碼
    • 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(‘a(chǎn)sync1 start’)
    // await異步函數(shù)的返回結(jié)果 resolve的結(jié)果會(huì)作為整個(gè)異步函數(shù)的promise的resolve結(jié)果->同步代碼
    // await后面的執(zhí)行代碼 就會(huì)變成.then后面的執(zhí)行函數(shù)->微任務(wù)
    // 也就是說(shuō) console.log(‘a(chǎn)sync1 end’) 這一段是相當(dāng)于then方法內(nèi)的 會(huì)被加入微任務(wù)中
    await async2();
    console.log(‘a(chǎn)sync1 end’)
    }

    async function async2() {
    console.log(‘a(chǎn)sync2’)
    }

    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í)行微任務(wù)
  • 輸出async1 end promise2
  • 最后執(zhí)行宏任務(wù)
  • 輸出setTimeout
  • 完整輸出:script start async1 start async2 promise1 script end async1 end promise2 setTimeout
  • 面試題三

    復(fù)制代碼
    • 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 微任務(wù)不會(huì)做任何延遲
    // return 4
    //2.直接返回Promise.resolve(4) 微任務(wù)推遲兩次
    // return Promise.resolve(4);
    //3.返回thenable對(duì)象
    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);
    })`
    這道面試題有些特殊,需要大家記住兩個(gè)結(jié)論

  • 如果返回的是thenable對(duì)象,那么微任務(wù)會(huì)推遲一次,thenable對(duì)象就是實(shí)現(xiàn)了Promise.then的那個(gè)函數(shù),具體可看代碼
  • 如果返回的是Promise.resolve(4),那么微任務(wù)會(huì)推遲兩次,這個(gè)相當(dāng)于是返回一個(gè)Promise之后又用了resolve,二者是等價(jià)的
  • 為了配合大家理解,我給大家畫了幾張圖,大家可以看看
  • [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-aMWrhIg9-1646846037009)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/569c204f981e42c5a98d2014e4594856~tplv-k3u1fbpfcp-zoom-1.image “上述是then中返回的三種情況”)]
    [外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-itzZizEq-1646846037013)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6e5976aafab541deace1e7dfdfa55ae6~tplv-k3u1fbpfcp-zoom-1.image “普通返回,不會(huì)推遲”)][外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(img-YB6D2Rjk-1646846037014)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/6d76aecd1449480ab33d9ffa352ff3e2~tplv-k3u1fbpfcp-zoom-1.image “返回thenable 推遲一次”)][外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來(lái)直接上傳(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)不一樣,需要記住以下幾點(diǎn)

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

    • 宏任務(wù): setTimeout、setInterval、IO事件、setImmediate、close事件
    • 微任務(wù): Promise的then回調(diào)、process.nextTick、queueMicrotask

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

  • next tick microtask queue
  • other microtask queue
  • timer queue
  • poll queue
  • pcheck queue
  • close queue
  • 復(fù)制代碼
    • 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(‘a(chǎn)sync1 start’)
    await async2()
    console.log(‘a(chǎn)sync1 end’)
    }

    async function async2() {
    console.log(‘a(chǎn)sync2’)
    }

    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í)行同步任務(wù)
  • 輸出script start async1 start async2 promise1 promise2 script end
  • 接著執(zhí)行微任務(wù),因?yàn)閚ode會(huì)優(yōu)先執(zhí)行nextTick這個(gè)微任務(wù)
  • 所以先輸出nextTick1 nextTick2
  • 在輸出其他微任務(wù),輸出async1 end promise3
  • 最后執(zhí)行宏任務(wù)
  • 輸出 setTimeout0 setImmediate
  • 因?yàn)檫@個(gè)定時(shí)器延時(shí)3ms執(zhí)行,所以會(huì)讓其他的宏任務(wù)先執(zhí)行完畢,才回去執(zhí)行這個(gè)定時(shí)器,所以最后輸出setTimeout2
  • 最后的輸出結(jié)果: script start async1 start async2 promise1 promise2 script end nextTick1 nextTick2 async1 end promise3 setTimeout0 setImmediate setTimeout2
  • 總結(jié)

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

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。