Node.js中使用計時器定時執行函數詳解_node.js
如果你熟悉客戶端JavaScript編程,你可能使用過setTimeout和setInterval函數,這兩個函數允許延時一段時間再運行函數。例如下面的程式碼, 一旦被載入到Web頁面,1秒後會在頁面文件後追加「Hello there」:
var oneSecond = 1000 * 1; // one second = 1000 x 1 ms
setTimeout(function() {
document.write('
Hello there.
');}, oneSecond);
而setInterval允許以指定的時間間隔重複執行函數。如果把下面的程式碼注入到Web頁面,會導致每秒鐘在頁面文件後面追加一句「Hello there」:
var oneSecond = 1000 * 1; // one second = 1000 x 1 ms
setInterval(function() {
}, oneSecond);
使用setTimeout延遲函數執行
setTimeout可以製定一個在將來某個時間把指定函數運行一次的執行計劃,例如:
var timeout = setTimeout(function() {
console.log("timed out!");
}, timeout_ms);
setTimeout回傳一個超時句柄,它是個內部對象,可以用它作為參數呼叫clearTimeout來取消計時器,除此之外這個句柄沒有任何作用。
使用clearTimeout取消執行計畫
一旦獲得了超時句柄,就可以用clearTimeout來取消函數執行計劃,像這樣:
var timeout = setTimeout(function() {
console.log("timed out!");
}, timeoutTime);
clearTimeout(timeout);
這個例子裡,計時器永遠不會被觸發,也不會輸出」time out!」這幾個字。你也可以在將來的任何時間取消執行計劃,就像下面的例子:
var timeout = setTimeout(function A() {
console.log("timed out!");
}, 2000);
setTimeout(function B() {
而clearTimeout(timeout);
}, 1000);
程式碼指定了兩個延遲執行的函數A和B,函數A計劃在2秒鐘後執行,B計劃在1秒鐘後執行,因為函數B先執行,而它取消了A的執行計劃,因此A永遠不會運作。
制定與取消函數的重複執行計畫
setInterval和setTimeout類似,但它會以指定時間為間隔重複執行一個函數。你可以用它來週期性的觸發一段程序,來完成一些類似清理,收集,日誌,獲取數據,輪詢等其它需要重複執行的任務。
下面程式碼每秒會向控制台輸出一句「tick」:
var period = 1000; // 1 second
setInterval(function() {
console.log("tick");
}, period);
如果你不想讓它永遠運作下去,可以用clearInterval()取消計時器。
setInterval回傳一個執行計畫句柄,可以把它當作clearInterval的參數來取消執行計畫:
var interval = setInterval(function() {
console.log("tick");
}, 1000);
// …
clearInterval(interval);
使用process.nextTick將函數執行延遲到事件循環的下一輪
有時客戶端JavaScript程式設計師用setTimeout(callback,0)將任務延遲一段很短的時間,第二個參數是0毫秒,它告訴JavaScript運行時,當所有掛起的事件處理完畢後立刻執行這個回調函數。有時候這種技術被用來延遲執行一些並不需要立刻執行的操作。例如,有時候需要在使用者事件處理完畢後再開始播放動畫或做一些其它的計算。
Node中,就像 「事件循環」的字面意思,事件循環運行在一個處理事件佇列的循環裡,事件循環工作過程中的每一輪就稱為一個tick。
你可以在事件循環每次開始下一輪(下一個tick)執行時調用回調函數一次,這也正是process.nextTick的原理,而setTimeout,setTimeout使用JavaScript運行時內部的執行隊列,而不是使用事件循環。
透過使用process.nextTick(callback) ,而不是setTimeout(callback, 0),你的回呼函數會在佇列內的事件處理完畢後立刻執行,它要比JavaScript的超時佇列快很多(以CPU時間來衡量)。
你可以像下面這樣,把函數延遲到下一輪事件循環再運行:
process.nextTick(function() {
my_expensive_computation_function();
});
注意:process物件是Node少數的全域物件之一。
阻塞事件循環
Node和JavaScript的執行時間採用的是單執行緒事件循環,每次循環,執行時透過呼叫相關回呼函數來處理佇列內的下個事件。當事件執行完畢,事件循環取得執行結果並處理下個事件,如此反复,直到事件隊列為空。如果其中一個回呼函數運行時佔用了很長時間,事件循環在那段時間就無法處理其它掛起的事件,這會讓應用程式或服務變得非常慢。
在處理事件時,如果使用了記憶體敏感或處理器敏感的函數,會導致事件循環變得緩慢,而且造成大量事件堆積,不能被及時處理,甚至堵塞隊列。
看下面阻塞事件循環的例子:
process.nextTick(function nextTick1() {
var a = 0;
while(true) {
}
});
process.nextTick(function nextTick2() {
console.log("next tick");
});
setTimeout(function timeout() {
console.log("timeout");
}, 1000);
當使用setTimeout時,回呼函數會被加入到執行計畫佇列,而在這個例子裡它們甚至不會被加入到佇列。這雖然是個極端例子,但你可以看到,執行一個處理器敏感的任務時可能會堵塞或拖慢事件循環。
退出事件循環
使用process.nextTick,可以把一個非關鍵性的任務推遲到事件循環的下一輪(tick)再執行,這樣可以釋放事件循環,讓它可以繼續執行其它掛起的事件。看下面例子,如果你打算刪除一個臨時文件,但是又不想讓data事件的回調函數等待這個IO操作,你可以這樣延遲它:
stream.end("my response");
process.nextTick(function() {
});
});
假設,你打算設計一個叫my_async_function的函數,它可以做某些I/O操作(例如解析日誌檔)的函數,並打算讓它週期性執行,你可以用setInterval這樣實現它:
var interval = 1000;
setInterval(function() {
my_async_function(function() {
});
},interval);//譯者註:前面「,interval」是我新增的,作者應該是錯誤遺漏了
譯者註:(下方粗體部分為譯者添加,非原書內容)
為了方便理解這部分內容,可以修改下作者的程式碼,讓它可以實際運作:
setInterval(function(){
(function my_async_function(){
})();
},interval);
運行下這段程式碼看看,你會發現,等待5秒鐘後,「hello 」被每隔1秒輸出一次。而我們期望是,當前my_async_function執行完畢(耗費5秒)後,等待1秒再執行下一個my_async_function,每次輸出之間應該間隔6秒才對。造成這種結果,是因為my_async_function不是串行執行的,而是多個在同時運行。
複製程式碼

熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

記事本++7.3.1
好用且免費的程式碼編輯器

SublimeText3漢化版
中文版,非常好用

禪工作室 13.0.1
強大的PHP整合開發環境

Dreamweaver CS6
視覺化網頁開發工具

SublimeText3 Mac版
神級程式碼編輯軟體(SublimeText3)

在iOS17中,您可以使用時鐘應用程式在iPhone上設定多個計時器,或使用Siri免持設定。我們在本文中討論了兩者。讓我們來看看它們。使用時鐘應用程式在iPhone上設定多個計時器打開iPhone上的時鐘應用程序,然後點擊右下角的計時器選項卡。現在,設定小時、分鐘和秒。您可以使用「標籤」和「計時器何時結束」選項來設定計時器的名稱以及計時器完成時的首選音調。這將幫助您區分計時器。完成後,點擊“開始”按鈕。然後,點擊右上角的「+」圖示。現在,重複上述步驟以在iPhone上設定多個計時器。您還可以瀏

什麼是iOS17上的多計時器?在iOS17中,Apple現在為用戶提供了在iPhone上一次設定多個計時器的能力。這是一個可喜的變化,許多人多年來一直期待的變化。時鐘應用程式在iOS16之前只允許使用者一次設定一個計時器,現在可用於啟動任意數量的計時器,使其成為您一次完成多個任務的理想選擇。您可以在計時器畫面中設定任意數量的計時器。啟動計時器後,所有活動計時器都將在鎖定螢幕介面和通知中心顯示為「即時活動」通知。從這裡,您可以查看計時器關閉、暫停或停止計時器的剩餘時間,而無需打開時鐘應用程式。當您在時鐘

基於無阻塞、事件驅動建立的Node服務,具有記憶體消耗低的優點,非常適合處理海量的網路請求。在海量請求的前提下,就需要考慮「記憶體控制」的相關問題了。 1. V8的垃圾回收機制與記憶體限制 Js由垃圾回收機

選擇一個Node的Docker映像看起來像是小事,但是映像的大小和潛在漏洞可能會對你的CI/CD流程和安全造成重大的影響。那我們要如何選擇一個最好Node.js Docker映像呢?

windows7計時器在哪裡,有些客戶使用win7時想要知道win7的倒數計時在哪裡,其實win7沒有自帶的計時器,但是有時鐘能夠記時,那麼下面就是有關windows7計時器位置介紹,最先根據個性化打開,隨後找到任務列和選單列的選項中,接著與謳歌自定,找到時鐘,選擇打開,這樣就能夠根據時鐘進行到技術了。非常的簡單迅速。 windows7計時器在哪裡在電腦螢幕空白,滑鼠右鍵,選擇開啟」個人化」。選擇開啟」工作列和功能表列」選項,開啟後,我們在任務欄的頁籤裡,下方有個狀態列地區,點擊自定按鍵點擊下面的」打

文件模組是對底層文件操作的封裝,例如文件讀寫/打開關閉/刪除添加等等文件模組最大的特點就是所有的方法都提供的**同步**和**異步**兩個版本,具有sync 字尾的方法都是同步方法,沒有的都是異
