【问题标题】:Flattening out nested callback展平嵌套回调
【发布时间】:2012-05-02 03:01:03
【问题描述】:

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

【问题讨论】:

  • 您给出的示例解决方案有什么特别问题?
  • 看起来是一个很棒的想法和一个很好的实现。有什么问题?
  • 你也可以试试这个:github.com/caolan/async为这类问题而生。
  • 问题是我从 Node.js 收到一个错误,说未定义错误或未定义集合。出于某种原因,当我嵌套回调时,正确的对象被传递下来。当我尝试采用这种扁平化风格时,它抱怨事情没有定义。我不知道如何让它传递必要的对象。我已将此评论添加到此问题。很抱歉模棱两可。

标签: javascript node.js mongodb callback


【解决方案1】:

您需要的是众多control flow libraries 之一,通过 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);
});

【讨论】:

  • 实际上async.series 不会将参数传递给下一个调用。他需要async.waterfall
  • 当我使用它时,结果数据集是否会被传递回链并返回给调用函数?我希望从这一系列回调中返回 cursor.toArray() 函数的结果。
  • 查看异步文档。使用瀑布流,每个函数的回调值作为参数传递给链中的下一个函数,最终函数的回调值作为“完成”回调函数的参数。您可以根据需要链接结果。我将更新我的答案以包含一个示例。
【解决方案2】:

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();

【讨论】:

    猜你喜欢
    • 2016-10-06
    • 2019-03-05
    • 2018-10-24
    • 1970-01-01
    • 2021-06-01
    • 2017-07-13
    • 2017-07-02
    • 2021-09-05
    • 2014-05-28
    相关资源
    最近更新 更多