2012-12-18 36 views
3

我試圖讓我的頭在何時使用process.nextTick。下面我使用異步庫來控制我的代碼流,並想知道我是否應該在結束回調中調用nextTick。我應該使用process.nextTick

async.parallel([ 
    function (callback) { 
     // do something 
     callback(data); 
    }, 
    function (callback) { 
     // do something 
     callback(data);   
    } 
], 
// callback 
function (data) { 
    process.nextTick(function() { 
     // do something 
    }); 
}); 
+0

是什麼讓你覺得你應該在那裏調用'nextTick'? – JohnnyHK

+1

我讀過[關於nextTick的文章](http://howtonode.org/understanding-process-next-tick),其中的一個例子是關於使回調異步的。所以我想知道是否應該考慮在所有回調中使用nextTick,以避免服務器負載過重時潛在的未來問題。我的測試在使用和不使用nextTick的情況下都能正常工作 - 所以仍然試圖在最佳使用時將我的頭包裹起來。 – leepowell

+1

其實很簡單。只有在當前回調完成執行並且任何已經排隊的回調已經運行之後,纔想延遲某些代碼的執行時才使用'nextTick'。 – JohnnyHK

回答

5

不知道你做某些事情「是,我沒有看到你需要在這種情況下使用nextTick任何原因到底是什麼。當你有理由推遲執行一個函數到下一次事件循環時,你可以使用nextTick。您可能需要閱讀Understanding process.nextTick瞭解更多詳情。

另外請注意,異步的parallel任務完成回調帶參數err, data,所以你應該做的:

async.parallel([ 
    function (callback) { 
     // do something 
     callback(null, data); 
    }, 
    function (callback) { 
     // do something 
     callback(null, data);   
    } 
], 
// callback 
function (err, data) { 
    if (err) throw err; 
    // do something 
}); 

的主要區別在於,最終調用回調函數,如果立即的並行任務之一返回錯誤(用truthy第一個參數調用callback)。

+0

我確實有一個問題 - 如果它有回調,是否會自動調用異步?所有的回調都放置在節點事件循環中,還是在有回調的情況下不會在節點異步中產生進程? – AlexGad

+1

不一定。回調只是一個被稱爲「稍後」的函數 - 沒有什麼內在的特殊之處;它只是簡單的函數調用,並且回調不會在事件循環中自動調度(事實上,這就是您可能使用'nextTick'的原因)。當然,「以後」的意思完全取決於你傳遞迴調的功能。例如,'function(cb){cb(); }'不是異步的,因爲你*知道*回調將被立即調用,在相同的調用堆棧上以及事件循環的相同迭代中調用。 – josh3736

+1

...這並不一定是壞的:考慮一個從數據庫中檢索數據的功能,但也會緩存數據。 'function get(key,cb){if(cache [key])cb(cache [key]); else getFromDb(key,function(dbresult){cache [key] = dbresult; cb(dbresult);}); }'該函數同步返回數據*,如果它被緩存(這是好事:它會讓你的程序更快),或者*異步*如果它需要從數據庫中獲取數據。 – josh3736

0

我的經驗是,對於async.parallel和其他類似的功能能正常工作,那你需要使所有任務明確異步;我喜歡異步庫,這是我對promise等的第一選擇,但如果不強制任務是異步的,可能會出現一些奇怪的行爲。

在這裏看到: https://github.com/caolan/async#common-pitfalls-stackoverflow

所以它應該是:

async.parallel([ 

function(cb){ 
    process.nextTick(function(){ 
      doSomePotentiallySyncThing(cb); 
    }); 
}, 

function(cb){ 
    process.nextTick(function(){ 
      doSomePotentiallySyncThing(cb); 
    }); 
}, 
function(cb){ 

    definitelyAsync(cb); // if it's **definitely** async, then we don't need process.nextTick 

} 
], function complete(err, results){ 

    // we are in the final callback 

}); 

我99%肯定這一點。