簡體   English   中英

在執行之前,JavaScript 中的異步承諾存儲在哪里?

[英]Where are asynchronous promises stored in JavaScript before execution?

我已經使用 JavaScript 幾年了,最近對高級 JavaScript 概念進行了大量研究。 我了解到函數回調存儲在通常稱為事件隊列或消息隊列的隊列中,這就是允許 JavaScript 異步操作的原因。

我從許多來源了解到,在事件隊列上的回調之前執行承諾。 我的個人實驗也證實了這種行為。 然而,兩者似乎都被推到了同一個隊列中。 如果承諾與其他所有回調共享相同的隊列,那么它們如何首先執行?

從邏輯上講,我認為承諾會被推送到具有比事件隊列中的回調更高的優先級的不同隊列,但我找不到任何來源來支持這一點。

我知道所有瀏覽器對事件隊列的處理方式不同,不同的環境會觀察到不同的行為。 但是,我一定錯過了一些東西。

這是實現定義的。 ECMAScript (JavaScript) 規范只要求在同步 JavaScript 代碼之后按順序執行then回調(和等待)的作業( EnqueueJob )。

在它之外發生的一切(在 Node 或瀏覽器 DOM API 中帶有 I/O 回調的“事件循環”)都由平台控制。

即: - Promise 回調調度是 JavaScript 和 ECMAScript 規范的一部分。 - 其他 I/O(例如計時器、文件訪問、DOM 用戶交互事件、網絡訪問)由主機平台而非 JavaScript 決定。 這可以是 Node.js 或瀏覽器 DOM API。

無論是一個隊列還是兩個隊列都是實現定義的。

我將選擇一種實現(Node.js)。 在 Node.js(和 Chrome)中,它們存儲在兩個不同的隊列中。

Promise 回調通過 V8 的 Isolate(執行環境)的RunMicrotasks方法“運行”。 這發生在next_tick.js

function runNextTicks() {
  if (tickInfo[kHasScheduled] === 0 && tickInfo[kHasPromiseRejections] === 0)
    runMicrotasks();
  if (tickInfo[kHasScheduled] === 0 && tickInfo[kHasPromiseRejections] === 0)
    return;

  internalTickCallback();
}

這會調用 V8 的微任務隊列。 另一方面,回調通過 node.cc 中的libuv運行。

有兩個隊列(libuv 和 V8),V8(微任務隊列)有機會在 libuv 的每兩個項目之間運行。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM