[英]javascript promises, the event loop, and the job queue
請考慮以下代碼:
function foo() {
console.log('foo');
new Promise(
function(resolve, reject) {
setTimeout(function() {
resolve('RESOLVING');
}, 5000);
}
)
.then(
function(value) {
console.log(value);
}
);
}
foo();
我試圖理解這里發生的事情:
new Promise
,直接運行“執行器函數”,並且當調用setTimeout
時,將安排向“事件隊列”添加新條目的操作(5秒后) then
添加到“作業隊列”的操作,在Promise
解決后組織調用傳遞的函數(記錄到控制台) setTimeout
回調時(在事件循環的某個刻度上), Promise
被解析,並且基於第2點, then
調用的函數參數被添加到“作業隊列”並隨后執行。 注意我說[一個“工作隊列”],因為有一些我不確定的事情; 哪個“工作隊列是嗎?”。 我理解它的方式,“作業隊列”鏈接到“事件隊列”上的條目。 那么這就是上面例子中的setTimeout
條目嗎? 假設在添加setTimeout
的回調之前(和之后)沒有向“事件隊列”添加其他事件,主代碼的條目(對foo的調用)是否(通常)已經消失(運行完成)那個時候因為then
的“作業隊列”條目沒有其他條目而不是setTimeout
的鏈接到?
- 在執行
new Promise
,直接運行“執行器函數”,並且當調用setTimeout
時,將安排向“事件隊列”添加新條目的操作(5秒后)
是。 更具體地說,調用setTimeout
使用瀏覽器的計時器機制來調度計時器; 大約五秒鍾后,計時器機制將作業添加到主要作業隊列中,該作業將調用您的回調。
- 因為調用
then
添加到“作業隊列”的操作,在Promise
解決后組織調用傳遞的函數(記錄到控制台)
對。 then
(使用單個參數)將一個履行處理程序添加到promise(並創建它返回的另一個promise)。 當promise解析時,調用處理程序的作業將添加到作業隊列中(但它是一個不同的作業隊列)。
- 當執行
setTimeout
回調時(在事件循環的某個刻度上),Promise
被解析,並且基於第2點,then
調用的函數參數被添加到“作業隊列”並隨后執行。
是的,但它不是同一個工作隊列。 :-)
主要的作業隊列就是事件處理程序和計時器回調等等。 主事件循環從隊列中獲取作業,將其運行至完成,然后選擇下一個作業等,如果沒有要運行的作業則空閑。
作業運行完成后,將運行另一個循環,該循環負責運行在該主作業期間計划的任何待處理的承諾作業。
在JavaScript規范中,主作業隊列稱為ScriptJobs,promise回調作業隊列為PromiseJobs。 在ScriptJob結束時,所有已排隊的PromiseJobs都會在下一個ScriptJob之前執行。 (在HTML規范中,它們的名稱是“task”[或“macrotask”]和“microtask”。)
是的,這確實意味着如果作業A和作業B都排隊,然后作業A被選中並安排一個承諾回調,則在作業B運行之前運行該承諾回調,即使作業B已排隊(在主隊列)首先。
注意我說[一個“工作隊列”],因為有一些我不確定的事情; 哪個“工作隊列呢?”
希望我已經涵蓋了上述內容。 基本上:
requestAnimationFrame
回調排隊到ScriptJobs隊列(主要隊列); 他們是“macrotasks”(或簡稱“任務”)。 我理解它的方式,“作業隊列”鏈接到“事件隊列”上的條目。
對於同樣的事情,這些只是不同的名稱。 JavaScript規范使用術語“作業”和“作業隊列”。 HTML規范使用“任務”和“任務隊列”和“事件循環”。 事件循環是從ScriptJobs隊列中獲取作業的。
那么這就是上面例子中的
setTimeout
條目嗎?
當計時器觸發時,作業將在ScriptJobs隊列中進行調度。
假設在添加
setTimeout
的回調之前(和之后)沒有向“事件隊列”添加其他事件,主代碼的條目(對foo的調用)是否(通常)已經消失(運行完成)那個時候因為then
的“作業隊列”條目沒有其他條目而不是setTimeout
的鏈接到?
基本上是的。 讓我們把它搞定:
foo
並調用它。 foo
,您執行console.log
,然后創建一個promise。 then
在promise中添加一個履行處理程序。 console.log
更多探索:
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.