2012-04-20 79 views
3

我有學習使用Node.js中的回調編程風格的問題令人沮喪。我有一個查詢到MongoDB數據庫。如果我傳遞一個函數來執行它的結果,但我寧願將它平坦化並讓它返回值。任何幫助或方向如何正確地做到這一點表示讚賞。這裏是我的代碼:展開嵌套回調

var getLots = function(response){ 
    db.open(function(err, db){ 
     db.collection('lots', function(err, collection){ 
      collection.find(function(err, cursor){ 
       cursor.toArray(function(err, items){ 
        response(items); 
       }) 
      }) 
     }) 
    }) 
} 

我想更多的東西是這樣的:

lots = function(){ 
    console.log("Getting lots") 
    return db.open(openCollection(err, db)); 
} 

openCollection = function(err, db){ 
    console.log("Connected to lots"); 
    return (db.collection('lots',findLots(err, collection)) 
    ); 
} 

findLots = function(err, collection){ 
    console.log("querying 2"); 
    return collection.find(getLots(err, cursor)); 
} 

getLots = function(err, cursor) { 
    console.log("Getting lots"); 
    return cursor.toArray(); 
} 

當最後一組數據將泡沫備份通過函數調用。

問題是我從Node.js得到一個錯誤,說err沒有被定義,或者這個集合沒有被定義。由於某些原因,當我嵌入回調時,正確的對象正在傳遞。當我嘗試去這個扁平化的風格時,它抱怨事物沒有被定義。我不知道如何讓它通過必要的對象。

+2

有什麼特別不妥你給出的示例解決方案? – 2012-04-20 13:59:49

+0

看起來像一個偉大的想法和良好的實施。有什麼問題? – mellamokb 2012-04-20 14:00:07

+1

你也可以試試這個:https://github.com/caolan/async爲這類問題而創建。 – freakish 2012-04-20 14:03:02

回答

4

您需要的是許多control flow libraries之一,可通過npm獲取節點並在Node.js wiki上編目。我的具體建議是caolan/async,您可以使用async.waterfall函數來完成這種類型的流程,其中每個異步操作必須按順序執行,並且每個流程都需要前一個操作的結果。

僞代碼示例:

function getLots(db, callback) { 
    db.collection("lots", callback); 
} 

function findLots(collection, callback) { 
    collection.find(callback); 
} 

function toArray(cursor, callback) { 
    cursor.toArray(callback); 
} 

async.waterfall([db.open, getLots, find, toArray], function (err, items) { 
    //items is the array of results 
    //Do whatever you need here 
    response(items); 
}); 
+0

實際上'async.series'不會傳遞參數給下一個調用。他需要'async.waterfall'。 – freakish 2012-04-20 15:09:06

+0

當我使用它時,得到的數據集會傳遞迴鏈並返回到調用函數?我想從這個系列的回調中返回cursor.toArray()函數的結果。 – 2012-04-20 17:26:04

+0

查看異步文檔。使用瀑布時,每個函數的回調值作爲參數傳遞給鏈中的下一個函數,最終函數的回調值是「完成」回調函數的參數。您可以根據需要鏈接結果。我會更新我的答案以包含一個示例。 – 2012-04-20 17:34:06

0

async爲良好的流動控制庫。 Frame.js提供了一些特定的優點,例如更好的調試和更好的同步功能執行安排。 (雖然它不是目前NPM像異步是)

下面是它看起來像在框架:

Frame(function(next){ 
    db.open(next); 
}); 
Frame(function(next, err, db){ 
    db.collection('lots', next); 
}); 
Frame(function(next, err, collection){ 
    collection.find(next); 
}); 
Frame(function(next, err, cursor){ 
    cursor.toArray(next); 
}); 
Frame(function(next, err, items){ 
    response(items); 
    next(); 
}); 
Frame.init();