3 回答

TA貢獻1789條經驗 獲得超10個贊
在node.js中沒有什么是真正的并行,因為它是單線程的。但是,可以按照您無法事先確定的順序安排和運行多個事件。而數據庫訪問等實際上是“并行”的,因為數據庫查詢本身在不同的線程中運行,但在完成時會重新集成到事件流中。
那么,如何在多個事件處理程序上安排回調?嗯,這是瀏覽器端javascript動畫中使用的一種常用技術:使用變量來跟蹤完成情況。
這聽起來像是一個黑客,它聽起來可能是混亂的,留下一堆全局變量圍繞著跟蹤,而用較少的語言。但在javascript中我們可以使用閉包:
function fork (async_calls, shared_callback) { var counter = async_calls.length; var callback = function () { counter --; if (counter == 0) { shared_callback() } } for (var i=0;i<async_calls.length;i++) { async_calls[i](callback); }}// usage:fork([A,B,C],D);
在上面的例子中,我們通過假設async和callback函數不需要參數來保持代碼簡單。您當然可以修改代碼以將參數傳遞給異步函數,并讓回調函數累積結果并將其傳遞給shared_callback函數。
補充答案:
實際上,即使是這樣,該fork()
函數也可以使用閉包將參數傳遞給異步函數:
fork([ function(callback){ A(1,2,callback) }, function(callback){ B(1,callback) }, function(callback){ C(1,2,callback) }],D);
剩下要做的唯一事情是累積A,B,C的結果并將它們傳遞給D.
更多補充答案:
我無法抗拒。在早餐期間一直想著這個。這fork()
是累積結果的實現(通常作為參數傳遞給回調函數):
function fork (async_calls, shared_callback) { var counter = async_calls.length; var all_results = []; function makeCallback (index) { return function () { counter --; var results = []; // we use the arguments object here because some callbacks // in Node pass in multiple arguments as result. for (var i=0;i<arguments.length;i++) { results.push(arguments[i]); } all_results[index] = results; if (counter == 0) { shared_callback(all_results); } } } for (var i=0;i<async_calls.length;i++) { async_calls[i](makeCallback(i)); }}
這很容易。這fork()
非常通用,可用于同步多個非同類事件。
Node.js中的示例用法:
// Read 3 files in parallel and process them together:function A (c){ fs.readFile('file1',c) };function B (c){ fs.readFile('file2',c) };function C (c){ fs.readFile('file3',c) };function D (result) { file1data = result[0][1]; file2data = result[1][1]; file3data = result[2][1]; // process the files together here}fork([A,B,C],D);
更新
此代碼是在存在像async.js或各種基于promise的庫之類的庫之前編寫的。我想相信async.js的靈感來自于此,但我沒有任何證據。無論如何..如果你今天想要這樣做,請看看async.js或promises。只需考慮上面的答案,就async.parallel之類的工作方式做了很好的解釋/說明。
為了完整起見,以下是您如何做到這一點async.parallel
:
var async = require('async');async.parallel([A,B,C],D);
請注意,async.parallel
它與fork
我們上面實現的功能完全相同。主要區別在于它將第一個參數傳遞給錯誤,D
并根據node.js約定將回調傳遞為第二個參數。
使用promises,我們將其編寫如下:
// Assuming A, B & C return a promise instead of accepting a callbackPromise.all([A,B,C]).then(D);

TA貢獻1850條經驗 獲得超11個贊
將異步調用連接在一起類似于
pthread_join
線程的工作方式。
自述文件顯示了使用自由式或使用Promise模式使用未來子模塊的一些很好的例子。來自文檔的示例:
var Join = require('join') , join = Join() , callbackA = join.add() , callbackB = join.add() , callbackC = join.add();function abcComplete(aArgs, bArgs, cArgs) { console.log(aArgs[1] + bArgs[1] + cArgs[1]);}setTimeout(function () { callbackA(null, 'Hello');}, 300);setTimeout(function () { callbackB(null, 'World');}, 500);setTimeout(function () { callbackC(null, '!');}, 400);// this must be called after all join.when(abcComplete);
添加回答
舉報