![](/img/trans.png)
[英]Significance of using setImmediate() and process.nextTick() in 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編譯器技巧(如streamline或co )來編寫看起來同步的代碼。 但在引擎蓋下,他們都使用異步回調模式。
我的建議是首先學習核心回調模式,以便你理解它。 這是一種巨大的痛苦。 從那里調查承諾(我個人喜歡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.