我在学习使用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的错误,说错误未定义或未定义集合。出于某种原因,当我嵌套回调时,正确的对象被传递下来。当我尝试这种扁平的风格时,它会抱怨事情没有定义。我不知道怎么让它传递必要的物品。
答案 0 :(得分:4)
您需要的是通过npm为节点提供的许多control flow libraries之一,并在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);
});
答案 1 :(得分:0)
async是一个很好的流量控制库。 Frame.js提供了一些特定的优点,例如更好的调试,以及更好的同步函数执行安排。 (虽然它目前在npm中并不像async那样)
以下是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();