簡體   English   中英

setTimeout 在 Node.JS 中是如何工作的?

[英]How does setTimeout work in Node.JS?

我想一旦它執行它就在隊列中,但是在隊列中是否有任何保證它將在 X 毫秒后准確調用? 或者隊列中其他更重的任務會延遲它嗎?

setTimeout 的語義與 web 瀏覽器中的語義大致相同:超時參數是執行前等待的最小毫秒數,不是保證。 此外,傳遞 0、非數字或負數將導致它等待最小毫秒數。 在 Node 中,這是 1 毫秒,但在瀏覽器中可能高達 50 毫秒。

原因是JavaScript沒有搶占JavaScript。 考慮這個例子:

setTimeout(function () {
  console.log('boo')
}, 100)
var end = Date.now() + 5000
while (Date.now() < end) ;
console.log('imma let you finish but blocking the event loop is the best bug of all TIME')

這里的流程是:

  1. 將超時時間安排為 100 毫秒。
  2. 忙等待 5000 毫秒。
  3. 返回事件循環。 檢查掛起的計時器並執行。

如果不是這種情況,那么您可以讓一位 JavaScript “中斷”另一位。 我們必須設置互斥鎖和信號量等,以防止這樣的代碼非常難以推理:

var a = 100;
setTimeout(function () {
  a = 0;
}, 0);
var b = a; // 100 or 0?

Node 的 JavaScript 執行的單線程性使其比大多數其他 styles 並發操作更簡單。 當然,權衡是程序的一個行為不端的部分可能會用無限循環阻塞整個事情。

這比搶占的復雜性更適合戰斗嗎? 那要看。

非阻塞的想法是循環迭代很快。 因此,為每個滴答進行迭代應該花費足夠短的時間,以使 setTimeout 在合理的精度范圍內准確(關閉可能 <100 毫秒左右)。

雖然理論上你是對的。 如果我編寫一個應用程序並阻止滴答聲,那么 setTimeouts 將被延遲。 所以要回答你的問題,誰能保證 setTimeouts 准時執行? 通過編寫非阻塞代碼,您可以將准確度控制到幾乎任何合理的准確度。

只要 javascript 在代碼執行方面是“單線程”的(不包括 web-worker 等),這種情況總會發生。 在大多數情況下,單線程性質是一個巨大的簡化,但需要非阻塞習語才能成功。

在瀏覽器或節點中嘗試此代碼,您會發現無法保證准確性,相反,setTimeout 會很晚:

var start = Date.now();

// expecting something close to 500
setTimeout(function(){ console.log(Date.now() - start); }, 500);

// fiddle with the number of iterations depending on how quick your machine is
for(var i=0; i<5000000; ++i){}

除非解釋器優化循環(它不在 chrome 上),否則你會得到成千上萬的東西。 去掉環,你會看到鼻子上有 500...

確保代碼執行的唯一方法是將 setTimeout 邏輯放在不同的進程中。

使用子進程模塊生成一個新的 node.js 程序,該程序執行您的邏輯並通過某種 stream(可能是 tcp)將數據傳遞給該進程。

這樣,即使在您的主進程中運行了一些長阻塞代碼,您的子進程已經自己啟動並在新進程和新線程中放置了一個 setTimeout,因此將在您期望的時候運行。

更復雜的情況是在硬件級別上,您運行的線程多於進程,因此上下文切換將導致(非常小的)您預期的時間延遲。 這應該可以忽略不計,如果重要的話,您需要認真考慮您要做什么,為什么需要這樣的准確性以及可以使用什么樣的實時替代硬件來完成這項工作。

通常,使用子進程並將多個節點應用程序作為單獨的進程與負載均衡器或共享數據存儲(如 redis)一起運行對於擴展代碼很重要。

setTimeout是一種Thread ,它持有給定時間的操作並執行。

setTimeout(function,time_in_mills);

在這里第一個參數應該是 function 類型,例如,如果你想在 3 秒后打印你的名字,你的代碼應該如下所示。

setTimeout(function(){console.log('your name')},3000);

要記住的關鍵點是,無論您想使用setTimeout方法做什么,都可以在 function 中執行。如果您想通過分配一些參數來調用其他方法,您的代碼應如下所示,

setTimeout(function(){yourOtherMethod(parameter);},3000);

快樂的nodejs編碼:)

setTimeout(callback,t)用於在至少 t 毫秒后運行回調。 實際延遲取決於許多外部因素,例如 OS 計時器粒度和系統負載。

因此,它有可能會在設置的時間之后被調用,但之前永遠不會被調用。

計時器不能超過 24.8 天。

暫無
暫無

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

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