91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

node.js中對Event Loop事件循環的理解與應用實例分析

發布時間:2020-08-26 01:43:07 來源:腳本之家 閱讀:151 作者:懷素真 欄目:web開發

本文實例講述了node.js中對Event Loop事件循環的理解與應用。分享給大家供大家參考,具體如下:

javascript是單線程的,所以任務的執行都需要排隊,任務分為兩種,一種是同步任務,一種是異步任務。

同步任務是進入主線程上排隊執行的任務,上一個任務執行完了,下一個任務才會執行。

異步任務是不進入主線程,而是進入一個 "任務隊列" 里,"任務隊列" 通知主線程,該異步任務才會進入主線程執行。

任務的運行機制如下:

1、所有同步任務在主線程上執行,形成一個 "執行棧",注意棧是先進后出的。

2、主線程外,有一個 "任務隊列" ,只要異步任務處理完有結果了,就在 "任務隊列" 中放置一個事件,注意隊列是先進先出的。

3、一旦 "執行棧" 中所有同步任務執行完畢。系統讀取 "任務隊列" 中的事件,對應的異步任務。放入 "執行棧" 中,開始執行。

4、主線程不斷重復第三步,這種循環從 "任務隊列" 中讀取事件處理的這種運行機制稱為Event Loop(事件循環)。

"執行棧" 中的同步代碼總是比 "任務隊列"中的異步任務之前運行。

function fun() {
  setTimeout(function () {
    console.log('異步任務');
  }, 0);
  console.log(1);
  console.log(2);
  console.log(3);
  console.log(4);
  console.log(5);
}
fun();

上面的代碼,console.log代碼寫在setTimeout后面,但仍然先執行。

"任務隊列" 是一個隊列,隊列的特性是先進先出。看下面代碼:

function fun() {
  console.log(1);
  setTimeout(function () {
    console.log(2);
    setTimeout(function () {
      console.log(3);
    }, 0);
  }, 0);
  console.log(4);
}
fun();

輸出結果為 1  4  2  3,打印 2 的setTimeout任務比打印 3 的setTimeout任務先進入隊列,所以會先運行。

對于異步操作,像ajax,只有操作成功后返回結果,才會進入 "任務隊列" 中,而不是調用的時候就放入隊列中。看下面代碼:

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
<body>
<script>
  function ajax() {
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://mail.163.com/', true);
    xhr.send();
    xhr.onreadystatechange = function () {
      if (xhr.readyState == 4 && xhr.status == 200) {
        console.log(xhr.responseText);
      }
    };
  }
  function fun() {
    console.log(1);
    ajax();
    setTimeout(function () {
      console.log(2);
    }, 1000);
    console.log(3);
  }
  fun();
</script>
</body>
</html>

ajax() 與 setTimeout 誰先進入隊列,誰先輸出,是需要看兩者消耗時間,誰更短。時間短的會先進入隊列先運行。

setTimeout 與 setInterval 運行機制一樣,都是在指定時間把事件插入到 "任務隊列" 尾部。區別是前者只執行一次,后者可反復執行。

node.js 還為我們提供了,process.nextTick 和 setImmediate 與 "任務隊列" 有關的方法。

process.nextTick 會把回調函數放在當前 "執行棧" 的尾部。也就是說是在讀取 "任務隊列" 之前運行。

function fun() {
  console.log(1);
  setTimeout(function () {
    console.log(2);
  }, 0);
  process.nextTick(function () {
    console.log(3);
    process.nextTick(function () {
      console.log(4);
    });
  });
  process.nextTick(function () {
    console.log(5);
  });
  console.log(6);
}
fun();

上面的代碼會輸出 1  6  3  5  4  2 ,注意process.nextTick會把回調函數放在 "執行棧" 的尾部。

同步代碼最先輸出 1  6,然后 3 的先放入尾部,然后 5 的跟在 3 后面。3先執行,然后把 4 放入到 5 的后面。5執行完后,再執行4,最后讀取 "任務隊列" 中的輸出2。

setImmediate 會把回調函數放在當前 "任務隊列" 的尾部。也就是下一次事件循環Event Loop時執行。

function fun() {
  console.log(1);
  setTimeout(function () {
    console.log(2);
  }, 0);
  setImmediate(function () {
    console.log(3);
  });
  console.log(4);
}
fun();

上面的代碼是會輸出 1  4  2  3 還是 1  4  3  2 是不確定的,因為setTimeout 與 setImmediate 都會在下一次事件循環Event Loop中觸發,所以輸出是不確定的。

希望本文所述對大家node.js程序設計有所幫助。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

淮北市| 托里县| 广州市| 忻城县| 伊宁县| 和政县| 拉孜县| 仪陇县| 嘉定区| 长丰县| 历史| 师宗县| 揭阳市| 龙南县| 巴彦县| 新乐市| 濮阳市| 喀喇沁旗| 盐津县| 灵寿县| 内丘县| 丰镇市| 阿城市| 江永县| 巫溪县| 河源市| 大姚县| 璧山县| 炎陵县| 内黄县| 安阳市| 蒙城县| 深泽县| 芒康县| 汨罗市| 邹平县| 阿荣旗| 绵竹市| 依安县| 囊谦县| 宁阳县|