4

在学习使用 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 或未定义集合。出于某种原因,当我嵌套回调时,正确的对象被传递下来。当我尝试采用这种扁平化风格时,它抱怨事情没有定义。我不知道如何让它传递必要的对象。

4

2 回答 2

4

您需要的是通过 npm 可用于 node 并在 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);
});
于 2012-04-20T14:46:49.503 回答
0

async 是一个很好的流控制库。Frame.js提供了一些特定的优势,例如更好的调试和更好的同步函数执行安排。(虽然它目前不像 async 那样在 npm 中)

这是 Frame 中的样子:

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();
于 2012-04-20T15:31:52.690 回答