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

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

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

前言

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

都說js是單線程的,不過它本身其實不是單線程,但是在瀏覽器中執(zhí)行時只分配一個線程進行執(zhí)行。

所以說js執(zhí)行是單線程的,一次只能進行一項任務,就是一件任務一件任務做,做完一件做下一件。

認識一個棧兩個隊列

一個調用棧Stack。

一個宏隊列,macrotask,也叫tasks。

一個微隊列,microtask,也叫jobs。

執(zhí)行過程

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

做完之后,調用棧就為空了。

然后將隊列(先微隊列后宏隊列)里面的首個任務提到調用棧來做,一件一件做完直到隊列中的任務都做完。

總結就是,先做同步的任務,再做微隊列的任務,再做宏隊列的任務。

異步任務怎么分配

這些異步任務包括但不限于:

以下分配給宏隊列:

setTimeout
setInterval
requestAnimationFrame
I/O
UI rendering

以下分配給微隊列:

Promise
Object.observe
MutationObserver

常見的宏隊列:setTimeout,常見的微隊列:Promise。

簡單例子

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

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

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

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

結果是(按標號加任務,按箭頭執(zhí)行):

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

難一點的例子

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

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

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

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

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

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

如何看呢,先看第一層,紅色代表同步,綠色微任務,藍色宏任務。

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

本來的執(zhí)行順序可能是這樣(我這里按照序號來表達順序了,請和簡單例子區(qū)分開來):

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

因為微任務執(zhí)行過程中可能會產生新的微任務。

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

所以接下來會按照加入隊列的順序執(zhí)行完四個微任務,這時候發(fā)現(xiàn)沒有新的微任務產生,才開始執(zhí)行宏任務:

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

(要記住微任務與宏任務隊列都存在時一定是微任務先執(zhí)行完再來執(zhí)行宏任務,即使是宏任務執(zhí)行產生的微任務也同理)

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

總結

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

相關文章

最新評論