Skip to main content

異步事件循環

@serverSerrverlesskiy

異步

在JavaScript中,異步是與加載網頁並行處理請求的主要工具。 現在無法想像Internet,在那裡對服務器的所有請求都將隨著頁面重新加載而發送。

來自服務器的任何數據都是異步請求的:發送了一個請求(XMLHttpRequest或XHR),並且代碼📟不等待其返回🔄而繼續執行。 服務器響應時,會向XHR對象發出通知,並運行在發送請求之前傳遞給它的回調函數。

如果您正確使用語言工具👅,則順序執行並在一個線程中進行的請求的執行不會以任何方式乾擾事件的接收和對事件的反應-一個人可以輕鬆地使用界面, 沒有註意到滯後,崩潰和凍結。

事件循環

Queue

JavaScript Event loop 是一個異步呼叫管理器。

為了使這個棘手的過程順利進行,JavaScript實現了一種機制來控制代碼執行的順序。 由於它是單線程語言,因此有必要“楔入”當前的執行上下文。 這種機制稱為事件循環。

來自英語, loop 轉換為 “循環”,完美體現了含義:我們正在處理回送隊列。

Event loop 調節上下文的執行順序-堆棧。 它是在觸發事件或調用函數時生成的。 對事件的響應放置在執行隊列中 event loop, 每個循環依次執行進入其中的代碼 📟 在這種情況下,綁定到事件的函數在當前執行上下文之後被調用。

在 JavaScript 中,同步和異步執行隊列一直在運行。 同步 - stack - 形成隊列並轉發到異步 - event loop - 函數調用⚙️,它將在當前計劃的可執行上下文之後執行。

為了使數據保持一致狀態,必須完成每個功能。 這是由於JavaScript的單線程和其他一些功能,例如功能的閉包 "languages" 編程。 因此,一個線程被表示為執行上下文的隊列,其中通過事件循環傳遞的函數是 "wedged".

描述

JavaScript是一種單線程語言:一次只能運行一個任務。 通常這沒什麼大不了的,但是現在想像您正在運行一個耗時30秒的任務...是的。 在執行此任務期間,我們等待30秒鐘,然後其他任何事情才能發生(默認情況下,JavaScript在主瀏覽器線程上運行,因此整個UI都將等待)now 現在是2021年,沒有人想要一個速度慢的站點。

幸運的是,瀏覽器為我們提供了JavaScript本身未提供的某些功能:Web API。 其中包括DOM API,setTimeout,HTTP請求等。 這可以幫助我們創建異步非阻塞行為。

當我們調用一個函數時,它將被添加到調用堆棧中。 調用堆棧是JS引擎的一部分,它與瀏覽器無關。 這是堆棧的經典視圖,即 first in, last out.當函數返回時,它會從堆棧中彈出。

function great() {
return 'Hello'
}

function respond() {
return setTimeout(() => alert('Hey!'), 1000)
}

great()
respond()

stack

響應函數返回 setTimeout 函數。 SetTimeout 通過以下方式提供給我們 Web-API: 它使我們可以在不阻塞主線程的情況下劃分任務。 這 Callback 我們傳遞給 setTimeout 功能, () => {返回 'Hey'} lambda函數已添加到 Web-API. 同時, setTimeoutresponde 從堆棧中彈出並返回其值。

timer

Web-API, 計時器一直運行到我們傳遞給它的第二個參數等待 1000ms。 回調不會立即添加到調用堆棧中,而是傳遞給稱為隊列的內容。

queue

這可能會造成混亂:這並不意味著在1000毫秒後將“回調”函數添加到調用堆棧中(從而返回一個值)! 它只是在1000毫秒後添加到隊列中。 但是在此隊列中,該函數必須等到輪到它為止。

現在這是我們大家一直在等待的部分。事件循環要做一件事的時間:將隊列連接到調用堆棧! 如果調用堆棧為空,也就是說,如果所有先前調用的函數都返回了它們的值並從堆棧中彈出,則隊列中的第一項將添加到調用堆棧中。 在這種情況下,沒有其他函數被調用,這意味著到 callback函數是隊列中的第一項。

qtoc

回調被推入調用堆棧,被調用並返回,並從堆棧中彈出。

result

觀看很有趣,但是如果不反复研究一個主題,就無法完全掌握一個主題。 如果運行以下命令,嘗試找出控制台中顯示的內容:

const foo = () => console.log('First')
const bar = () => setTimeout(() => console.log('Second'), 500)
const baz = () => console.log('Third')

bar()
foo()
baz()

讓我們看看在瀏覽器中運行以下代碼時會發生什麼:

br

我們稱之為 bar, 這將返回 setTimeout 功能。 Callback 我們傳遞給 setTimeout 被添加到 Web API, setTimeoutbar 從調用堆棧彈出功能。

計時器開始計時 foo 被稱為和日誌 First. foo 退貨 undefined, baz 被稱為 callback 已添加到隊列 baz logs Third. 事件循環發現baz返回後,調用棧為空,然後將回調添加到調用棧。 Callback 日誌 Second.

希望這會讓您對 event loop!

不必擔心是否仍然令人困惑,最重要的是了解某些錯誤或特定行為可能來自何處。

問題?

Problem

寫給 Discord 聊天。

問題:

Question

異步是:

1.一種工具,用於顯示同步流中函數的執行上下文 2.逐行執行代碼的工具 3.一種與網頁加載並行處理請求的工具

異步呼叫管理器:

  1. stack
  2. Event loop
  3. JavaScript

函數調用位於:

1.堆疊 2.一堆 3.循環

延遲一毫秒執行代碼的工具:

  1. delay
  2. heap
  3. setTimeout

為了了解您學到了多少本課程,請對 mobile application 我們學校就這個話題。

Sumerian school

鏈接:

  1. Explaining how EventLoop works in JavaScript
  2. How to manage event loop in JavaScript
  3. Javascript reference
  4. Article: Explaining Event Loop in Javascript Using Rendering
  5. Article: JavaScript Visualized: Promises & Async / Await

貢獻者 ✨

感謝這些好人 (emoji key):


AlisaNasibullina

📖

Dmitriy Vasilev

💵

Resoner2005

🐛 🎨

Become a Patron!