簡體   English   中英

使用process.nextTick或setImmediate - node.js創建等待函數

[英]Creating a waiting function using process.nextTick or setImmediate - node.js

我正在編寫一些Node.js,我認為,來自Java背景,我應該弄清楚如何創建自己的“等待”功能。 顯然,它會有所不同,因為Java被設計為多線程而Node不是。 無論如何,我想在Node中想要的功能是我想自己創建一個阻塞函數 - 這樣如果程序中的某個布爾值沒有設置,我可能想調用process.nextTick()直到boolean得到設置。

所以它會是:

    var bool = false;

    function foo(){
    var b = baz();
    }

    function baz(){

        while(!bool){
           process.nextTick(function() {
           return baz(arguments);
        });
      }

    return {};
    }

   function setBool(number) {

       setTimeout(function () {
            bool = false;
       }, number);
   }

   process.nextTick(wait);
   setBool(3000);

所以這個問題有兩個方面:

(1)這是在Node.js中實現等待類型功能的最佳方法嗎?

(2)如果我調用baz(參數)而不是baz函數(遞歸地)在執行方面會發生什么? 通常,當你想要函數X的返回值,但函數X在返回之前調用自己幾次,這是否會造成任何問題? 這沒什么大不了的,結果是相同的回報價值? 我以前考慮過這個問題,但從未真正擔心或調查過它。

不要在Node.j中'等待'。 “等待”阻止所有其他執行。 這是一個重要的注意事項,因為如果你阻止,那么布爾值永遠不能設置改變。 JavaScript,特別是在Node中,使用事件驅動模型。 這樣做,那時候。

那么最好的方法呢? 這是基於意見,但這是一種方式:

var bool = false;

function foo() {
    console.log('Listening for true');
    baz(function() {
        //Do something when called
        console.log('It\'s finally true!');
    });
}

function baz(callback) {
    setImmediate(function() {
        if (bool)
            callback();
        else
            baz(callback);
    });
}

foo();
setTimeout(function() {
    console.log('Setting to true');
    bool = true;
}, 4000);

其他答案已經說明了重要的部分:不,這不會奏效。 我想發布這個內容,以提供更多關於為什么這不起作用的背景知識。

在幕后,node.js正在運行一個事件調度循環。 存在一系列事件(包括,至少在概念上,“app start”,“incoming message”,“socket connection”,“file io complete”等)。 當事件發生時,事件調度程序將事件從隊列中拉出並調用與該事件關聯的任何Javascript函數。 一旦回調函數完成,調度就會將下一個事件從隊列中拉出,處理它等等。這是完全同步的 - 下一個事件在當前事件完成之前無法處理。

所以當你有這樣的代碼時:

var done = false;
while (!done) {
    process.nextTick(function () {
       done = true;
    });
}

怎么了? 您輸入while循環,process.nextTick 將事件放在事件隊列上,以便在下次運行事件循環時進行處理。 然后你的代碼循環回來,檢查完成(仍為假),排隊另一個事件等。

由於事件循環在函數返回之前無法處理排隊事件,因此事件循環會卡住,並且不會調用process.nextTick的回調。 你確保從未有過“nextTick”。

無法在純Javascript代碼中執行同步等待。 在Node.js中,您可以在C擴展中執行此操作(這就是實現fs.readFileSync之類的東西)。 您可以使用一些Javascript編譯器技巧(如streamlineco )來編寫看起來同步的代碼。 但在引擎蓋下,他們都使用異步回調模式。

我的建議是首先學習核心回調模式,以便你理解它。 這是一種巨大的痛苦。 從那里調查承諾(我個人喜歡Bluebird作為承諾實現,或者如果你使用ES6,你可以使用內置的promises)或許多異步幫助庫之一。

在Javascript中執行此操作的典型方法是使用promise。 例如,使用“q”承諾(請參閱https://github.com/kriskowal/q ),您將擁有:

var deferred = Q.defer();


deferred.promise.then(function(myParam) {
    var b = baz();
});
function baz(){
    return {/*whatever you want*/};
}

而且,代碼中的其他地方:

deferred.resolve(myParam);

在此示例中,您確保僅在滿足某些條件后才調用“baz”。 基本上,不是將布爾值設置為true,而是“解析”延遲對象。

暫無
暫無

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

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