簡體   English   中英

為什么 setTimeout 不取消我的循環?

[英]Why isn't setTimeout cancelling my loop?

我想知道一個 JavaScript 的while語句(在 Chrome 的控制台中)可以在一毫秒內增加一個變量多少次,所以我很快就把這個片段直接寫到了控制台中:

var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }

問題是它永遠運行。
為什么會發生這種情況,我該如何解決?

這又回到了 JavaScript 1的單線程特性。 發生的事情幾乎是這樣的:

  1. 您的變量已分配。
  2. 您安排了一個函數,以設置run = false 該計划目前的功能是運行(或任何其他當前活動)運行。
  3. 你有你的無限循環並留在當前函數中。
  4. 在你的無限循環( never )之后, setTimeout()回調將被執行並且run=false

如您所見, setTimeout()方法在這里不起作用。 您可以通過檢查while條件中的時間來解決這個問題,但這會干擾您的實際測量。

1至少出於更實際的目的,您可以將其視為單線程。 實際上有一個所謂的“事件循環”。 在該循環中,所有函數都會排隊,直到它們被執行。 如果您排隊一個新函數,它會被放置在該隊列中的相應位置。 當前功能完成之后,發動機將在下次函數從隊列(相對於作為引入的定時,例如,通過setTimeout()並執行它。
結果在每個時間點只執行一個函數,從而使執行幾乎是單線程的。 事件有一些例外情況,在下面的鏈接中進行了討論。


以供參考:

JavaScript 是單線程的,因此當您處於循環中時,不會執行任何其他操作。

為了保持Chrome的真實速度,而不必不斷檢索時間來計算速度,您可以嘗試以下JS代碼:

var start = new Date().getTime()
var i = 0
while(i<1000000)
{
    i++
}
var end = new Date().getTime()
var delta = end-start
var speed = i/delta
console.log(speed + " loops per millisecond")

Javascript 是單線程的,這意味着它一次只按順序運行一條指令。

與許多其他語言和庫一樣,事件系統由事件循環處理。 事件循環基本上是一個循環,它在每次迭代時檢查隊列中的消息,並調度事件。

在 javascript 中(就像在實現這種模式的語言中一樣),當堆棧為空時,即所有函數都有返回時,換句話說,在程序代碼的末尾,將調用事件循環。

你的“真實”程序在幕后看起來像這樣:

var run = true, i = 0;
setTimeout(function(){ run = false; }, 1);
while(run){ i++; }

while(true) {
/*
 * check for new messages in the queue and dispatch
 * events if there are some
 */
  processEvents();
}

因此,永遠不會處理來自時鍾的消息說超時結束。

關於事件循環的更多信息: https : //developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/EventLoop


當然它有點復雜,請在此處查看這些示例: JavaScript 是否保證是單線程的? ( tl;dr:在一些瀏覽器引擎中,一些外部事件不依賴於事件循環,一旦發生就會立即觸發,搶占當前任務。但 setTimeout 不是這種情況,它只是向隊列中添加一條消息並且永遠不會立即開火。)

While 循環不訪問 setTimeout。 您有設置運行為真的代碼,然后它永遠不會變為假。

JavaScript 具有單線程,並且在任何地方都有單線程。

我認為這個問題很好: JavaScript 是否保證是單線程的?

當您的代碼處於循環中時,其他 ocde 不會執行並阻塞。

暫無
暫無

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

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