2011-12-18 22 views
2

我想知道什麼是處理node.js中的多個併發操作的最佳方式。例如,讓我們假設給定的HTTP請求需要在提交響應之前進行3次數據庫查詢,但每個請求都是獨立的。我目前的幼稚執行工作是這樣的(在僞代碼中)Node.js中的多個併發操作

doRequest1(query, function (response1) { 
    doRequest2(someQuery, function (response2) { 
     doRequest3(someQuery, function (response3) { 
      renderHTML(response1,response2,response3); 
     }); 
    }); 
}); 

有沒有更好的方法來做到這一點?等待每個查詢的響應啓動下一個查詢似乎是浪費。

回答

7

您應該使用流量控制庫,如異步

https://github.com/caolan/async

或臺階

https://github.com/creationix/step

編輯:與異步

async.parallel([ 
    function(callback){ 
     doRequest1(query, callback); 
    }, 
    function(callback){ 
     doRequest2(query2, callback); 
    }, 
    function(callback){ 
     doRequest3(query3, callback); 
    }, 
], 
function(err, results){ 
    if (err) { 
     renderError(err); 
    } else { 
     renderHTML(results[0], results[1], results[2]); 
    } 
}); 

添加一個例子,如果你想讓每一個函數按系列運行(等待前面的函數完成),則可以使用async.series而不是async.parallel。如果查詢取決於先前查詢的結果,則可以使用async.waterfall。如果查詢之間存在複雜的依賴關係圖,則可以使用async.auto。

7

Gruikya的回答指出你應該做的,在這裏它是如何工作的幕後:

var unfinished = 3 
var noop = function() {} 
var data1, data2, data3 
doRequest1(query1, function(err, results) { 
    if (err) return cb(err), cb = noop 
    data1 = results 
    if (--unfinished === 0) done() 
} 
doRequest2(query2, function(err, results) { 
    if (err) return cb(err), cb = noop 
    data2 = results 
    if (--unfinished === 0) done() 
} 
doRequest3(query3, function(err, results) { 
    if (err) return cb(err), cb = noop 
    data3 = results 
    if (--unfinished === 0) done() 
} 
function done() { 
    // do stuff with the data here 
    cb(null) // everything ok 
}