簡體   English   中英

node.js setTimeout()是否正常工作?

[英]Is node.js setTimeout() working?

我是Node.js的新手。 我需要做些什么才能使setTimeout()工作嗎?

這是一個代碼片段。

完成后將appMsg.doneLoadTables = true設置的異步代碼

do {
  console.log('waiting ...   ' + appMsg.doneLoadTables);
  setTimeout(function() { console.log('waiting ...'); }, 1000);
} while (!appMsg.doneLoadTables);

症狀:

  • (雖然對console.log的兩個調用是相似的,但只有第一個會打印appMsg.doneLoadTables的值。)每個結果都包含該值。
  • 兩次調用console.log的間隔比1000毫秒小得多。 (我懷疑間距與計算機可以處理此處所示循環的速度一樣快。)
  • 雖然我希望異步例程可以在我在此指定的延遲期間繼續處理,但我從未見過這樣的循環; 好像該循環占用了所有處理資源,並阻止了異步例程完成其工作並阻止了將結束該循環的變量。

我對Node 4.2.1有此經驗; 安裝Node 5.0.0后,我仍然有這種體驗。

我已經看到關於setTimeout()的類似問題在這里已經問過很多次了。 我希望我在setTimeout()中使用IIFE可以使這個問題與所有問題區分開。

在此先感謝您提供的任何幫助...

JavaScript是單線程的。 setTimeout 不是一種sleep形式,它會在該行暫停代碼。 它的工作方式是“安排”回調以供以后使用,並在堆棧耗盡(引擎不執行任何操作)且至少n毫秒后執行時執行,其中n是您放置的延遲(以毫秒為單位)。

現在您的代碼不起作用,因為它永遠不會退出循環。 該代碼沒有機會執行其他代碼(您希望運行並更改appMsg.doneLoadTables的值的代碼)。 它所做的全部工作都會記錄“正在等待... [某物]”。

本質上,您正在輪詢。 您可以使用setInterval代替。 appMsg.doneLoadTablestrue ,可以使用clearInterval停止輪詢。

我不是100%確定您的目標是什么...但是,也許此代碼段將您帶到了想要去的地方(我選擇了setTimeout而不是setInterval ):

var appMsg = {doneLoadTables: false};

var stillLoading = function() {
    if(false === appMsg.doneLoadTables) {
        console.log('waiting ...   ' + appMsg.doneLoadTables);
        setTimeout(stillLoading, 50);
    }
    else {
        console.log('Loading complete.');
        process.exit();
    }
}

stillLoading();
setTimeout(function(){
    console.log('Setting appMsg.doneLoadTables = true');
    appMsg.doneLoadTables = true;
}, 1000);

該腳本每50毫秒輪詢一次狀態,並在1秒后精確標記為“完成”。

輸出看起來像這樣

waiting ...   false
waiting ...   false
waiting ...   false
waiting ...   false
...
Setting appMsg.doneLoadTables = true
Loading complete.

(雖然對console.log的兩個調用是相似的,但只有第一個會打印appMsg.doneLoadTables的值。)每個結果都包含該值。

這是正確的行為,因為您永遠不會退出while循環。 您將停留在永遠循環的同一事件框架中。

兩次調用console.log的間隔比1000毫秒小得多。 (我懷疑間距與計算機可以處理此處所示循環的速度一樣快。)

這再次是正確的行為,因為傳遞給setTimeout的回調將永遠不會執行,除非退出從未執行的do-while循環。 因此,您只需繼續調用第一個console.log語句,然后將回調添加到事件循環即可在1000毫秒內執行,而不會給它(您傳遞的回調)執行的機會。

雖然我希望異步例程可以在我在此指定的延遲期間繼續處理,但我從未見過這樣的循環; 好像該循環占用了所有處理資源,並阻止了異步例程完成其工作並阻止了將結束該循環的變量。

循環永遠不會結束,因為沒有實現該循環的邏輯。 “異步例程”無法繼續,因為這將需要退出當前事件框架(運行無限循環),並開始下一個將您回調傳遞給setTimeout的事件框架。

希望我的解釋將幫助您了解異步JavaScript的工作方式。

暫無
暫無

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

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