欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

js在瀏覽器中的event loop事件隊(duì)列示例詳解

 更新時(shí)間:2021年11月02日 10:26:14   作者:在下月亮有何貴干  
大家都知道js是單線程的腳本語(yǔ)言,在同一時(shí)間只能做同一件事,為了協(xié)調(diào)事件、用戶交互、腳本、UI渲染和網(wǎng)絡(luò)處理等行為,防止主線程阻塞,Event Loop方案應(yīng)運(yùn)而生,這篇文章主要給大家介紹了關(guān)于js在瀏覽器中的event loop事件隊(duì)列的相關(guān)資料,需要的朋友可以參考下

前言

以下內(nèi)容是js在瀏覽器中的事件隊(duì)列執(zhí)行,與在nodejs中有所區(qū)別,請(qǐng)注意。

都說(shuō)js是單線程的,不過(guò)它本身其實(shí)不是單線程,但是在瀏覽器中執(zhí)行時(shí)只分配一個(gè)線程進(jìn)行執(zhí)行。

所以說(shuō)js執(zhí)行是單線程的,一次只能進(jìn)行一項(xiàng)任務(wù),就是一件任務(wù)一件任務(wù)做,做完一件做下一件。

認(rèn)識(shí)一個(gè)棧兩個(gè)隊(duì)列

一個(gè)調(diào)用棧Stack。

一個(gè)宏隊(duì)列,macrotask,也叫tasks。

一個(gè)微隊(duì)列,microtask,也叫jobs。

執(zhí)行過(guò)程

js就是執(zhí)行全局Script同步代碼,這中間碰到一些異步任務(wù)先加進(jìn)對(duì)應(yīng)的隊(duì)列。

做完之后,調(diào)用棧就為空了。

然后將隊(duì)列(先微隊(duì)列后宏隊(duì)列)里面的首個(gè)任務(wù)提到調(diào)用棧來(lái)做,一件一件做完直到隊(duì)列中的任務(wù)都做完。

總結(jié)就是,先做同步的任務(wù),再做微隊(duì)列的任務(wù),再做宏隊(duì)列的任務(wù)。

異步任務(wù)怎么分配

這些異步任務(wù)包括但不限于:

以下分配給宏隊(duì)列:

setTimeout
setInterval
requestAnimationFrame
I/O
UI rendering

以下分配給微隊(duì)列:

Promise
Object.observe
MutationObserver

常見的宏隊(duì)列:setTimeout,常見的微隊(duì)列:Promise。

簡(jiǎn)單例子

    console.log("同步任務(wù)1");

    setTimeout(() => {
      console.log("宏任務(wù)");
    });

    new Promise((resolve, reject) => {
      console.log("同步任務(wù)2");
      resolve("微任務(wù)");
    }).then((data) => {
      console.log(data);
    });

    console.log("同步任務(wù)3");

結(jié)果是(按標(biāo)號(hào)加任務(wù),按箭頭執(zhí)行):

需要注意的是Promise的第一層沒有執(zhí)行回調(diào)之前是同步的,也就是上面的同步任務(wù)2。

難一點(diǎn)的例子

    console.log("同步任務(wù)1");

    console.log("同步任務(wù)2");

    new Promise((resolve, reject) => {
      console.log("同步任務(wù)3");
      setTimeout(() => {
        console.log("宏任務(wù)1");
        Promise.resolve()
          .then(() => {
            console.log("微任務(wù)5");
          })
          .then(() => {
            console.log("微任務(wù)6");
          });
      });
      resolve("微任務(wù)1");
    })
      .then((data) => {
        console.log(data);
        return "微任務(wù)3";
      })
      .then((data) => {
        console.log(data);
      });

    setTimeout(() => {
      console.log("宏任務(wù)2");
    }, 0);

    new Promise((resolve, reject) => {
      resolve("微任務(wù)2");
    })
      .then((data, resolve) => {
        console.log(data);
        return "微任務(wù)4";
      })
      .then((data) => {
        console.log(data);
      });

    console.log("同步任務(wù)4");

如何看呢,先看第一層,紅色代表同步,綠色微任務(wù),藍(lán)色宏任務(wù)。

我們會(huì)把同步任務(wù)執(zhí)行完,然后看見微任務(wù)有倆,宏任務(wù)也有倆。

本來(lái)的執(zhí)行順序可能是這樣(我這里按照序號(hào)來(lái)表達(dá)順序了,請(qǐng)和簡(jiǎn)單例子區(qū)分開來(lái)):

但是沒那么順利,執(zhí)行到標(biāo)號(hào)6時(shí)不一樣了。

因?yàn)槲⑷蝿?wù)執(zhí)行過(guò)程中可能會(huì)產(chǎn)生新的微任務(wù)。

上面的微任務(wù)1執(zhí)行完會(huì)把微任務(wù)3加在微任務(wù)2后面,也就是微任務(wù)2執(zhí)行完也輪不到宏任務(wù),會(huì)繼續(xù)執(zhí)行新的微任務(wù)直到微任務(wù)隊(duì)列暫時(shí)為空。

所以接下來(lái)會(huì)按照加入隊(duì)列的順序執(zhí)行完四個(gè)微任務(wù),這時(shí)候發(fā)現(xiàn)沒有新的微任務(wù)產(chǎn)生,才開始執(zhí)行宏任務(wù):

但是需要注意的是,上面執(zhí)行到標(biāo)號(hào)5時(shí)又不一樣了,宏任務(wù)一執(zhí)行后又產(chǎn)生了新的微任務(wù),所以宏任務(wù)兩個(gè)并沒有順利連續(xù)執(zhí)行,而是被插入的微任務(wù)攔住了。

(要記住微任務(wù)與宏任務(wù)隊(duì)列都存在時(shí)一定是微任務(wù)先執(zhí)行完再來(lái)執(zhí)行宏任務(wù),即使是宏任務(wù)執(zhí)行產(chǎn)生的微任務(wù)也同理)

所以最后的答案,如果存在不理解的,可以在認(rèn)真回顧一下上文:

總結(jié)

到此這篇關(guān)于js在瀏覽器中的event loop事件隊(duì)列的文章就介紹到這了,更多相關(guān)js event loop事件隊(duì)列內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論