【问题标题】:Async mongodb find within loop finishing early before returning all data在返回所有数据之前,异步 mongodb find inside loop 提前完成
【发布时间】:2015-01-05 11:50:02
【问题描述】:

我正在使用 Async 实用程序模块从 Mongodb 数据库中返回项目。我想异步进行。我在尝试退货时遇到问题。

我想在所有User.find()'s 完成后触发回调,现在async.each() 正在提前终止,并且只在它应该全部返回时从数据库中给我一个项目。

代码如下:

async.each(lessons, function(lesson, next) { // For each item in lesson array
    if (_.isEmpty(lesson.lesson_grades) == true) { // Check if the grades array is empty
        return;
    } else {
        async.each(lesson.lesson_grades, function(grade, next) { // For each grade in grade array
            User.find({ // Find user from grade user_id
                _id: grade.user_id,
            }, '-salt -hashedPassword', function(err, user) {

                grade["name"] = user[0].name; // Add name
                grade["email"] = user[0].email; // Add email

                next(); // !! I think this is where the problem lies, it fires next() once the first item has been returned - so it doesn't get to the other items !!
            });
        }, function(err) {
            next(lessons);
        });
    }
}, function(lessons, err) {
    return res.json(200, lessons); // Return modified lessons (with name and email) to browser, currently only returns one but returns them all if a setTimeout() is added, making it a premature callback problem
});

有人可以为我指出正确的方向吗?我应该跟踪迭代吗?任何帮助将不胜感激。

【问题讨论】:

    标签: javascript node.js mongodb asynchronous


    【解决方案1】:

    异步遵循的约定是回调函数接受两个参数:错误和结果,按顺序。错误和结果之间的区别很重要,因为如果异步接收到错误,它会立即结束。说function(err) { next(lessons); } 的部分是错误的 - async 将lessons 误解为错误,因为它是真实的。它应该是:

    function(err, result) {
        next(err, result);
    }
    

    或者实际上您可以将函数替换为next

    另外,接近尾声的function(lessons, error) 应该是function(error)

    另一件需要注意的事情:您必须确保每个回调都只被调用一次。但如果它运行if 块而不是else 块,则永远不会调用next;异步永远不会完成。它不会阻止其他代码运行,但永远不会到达return res.json(200, lessons);。 (它也可能泄漏内存,我不确定。)

    最后一件事:在回调中返回结果不会做任何事情。看起来您正试图从同步函数中调用所有这些异步代码;这不起作用。 res.json 将被调用,但如果它返回一个值,那么您可能想将该值用作来自其他地方的另一个回调函数的参数。但我需要更多关于你想要做什么的信息。

    【讨论】:

    • 感谢您花时间回答。我已经按照您的建议进行了更改,但我仍然遇到同样的问题。你能指导我如何重写它吗?自从您发布此答案以来,我一直在尝试一整天。谢谢。
    • 您是如何从中获得输出的?另外,请注意我对答案的更改 - 最后的函数不应该有 lessons 作为参数(它应该是一个闭包变量)。
    猜你喜欢
    • 1970-01-01
    • 2020-04-08
    • 1970-01-01
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2015-12-01
    • 1970-01-01
    相关资源
    最近更新 更多