簡體   English   中英

棘手的setTimeout序列

[英]tricky setTimeout sequence

setTimeout調用集,間隔為0、1、2、3。

 function f() { setTimeout(function a() {console.log(10);}, 3); setTimeout(function b() {console.log(20);}, 2); setTimeout(function c() {console.log(30);}, 1); setTimeout(function d() {console.log(40);}, 0); } f(); 

輸出:(來自chrome。希望其他瀏覽器也一樣)

三十

40

20

10

有人可以清楚地解釋為什么訂購不是30、40、10、20嗎? 據說瀏覽器至少維持10毫秒或(規定)4毫秒的間隔。 如果是這樣,請使用時間量度或解釋該行為的便利方式來驗證輸出。 為了了解這種語言的強大功能,我錯過了什么細節?

編輯:

我知道這些功能是異步的。 我已經讀過約翰·雷西格(John Resig)的博客幾次。 而且我知道setTimeout的回調不能保證在指定的時間間隔執行。

更准確地說,我希望能有一個可以從執行隊列,事件循環,調用堆棧和計時器的角度解釋行為的解釋。

為了了解計時器在內部的工作方式,有一個重要的概念需要探討:不能保證計時器的延遲。 由於瀏覽器中的所有JavaScript都在單線程上執行,因此異步事件(例如鼠標單擊和計時器)僅在執行中存在空缺時才運行。

請參閱了解更多詳情

正如@Jebin在對OP的評論中指出的那樣,您在這里遇到了競爭狀況。

規格如下: https : //html.spec.whatwg.org/multipage/webappapis.html#dom-windowtimers-settimeout

步驟13是我們等待的地方,等待可能在腳本當前正在執行時發生。 請參閱http://jsbin.com/faguli/edit?js,console-在此示例中,由於腳本花費很長時間才能到達下一個setTimeout ,因此首先記錄“ 10”。

猜測,在Chrome中,第3個setTimeout的任務在JS管理對setTimeout的第4個調用之前排隊。

因此,盡管給出了不同的答案,但在這種情況下,Chrome和Firefox都符合規范。

確定性的一種方法是將setTimeout調用作為微任務的一部分處理,然后從那里啟動計時器,但是setTimeout是olllllld API,因此此處的更改可能會中斷網絡。

暫無
暫無

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

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