node.js - Mongoose 升级后,异步不会在回调中返回数据

标签 node.js mongodb asynchronous mongoose bluebird

在我的项目中,我使用async对数据库进行异步查询,我有这段代码:

async.auto({
        one: function(callback){
            getFriendsIds(userId, callback)
        },
        two: ['one', function(callback, results){
            getFriendsDetails(results.one, callback);
        }],
        final: ['one', 'two', function(callback, results) {
            res.status(200).send(results.two);
            return;
        }],
    }, function(err) {
        if (err) {
            sendError(res, err);
            return;
        }
    });

返回好友 ID 的方法如下所示:

function getFriendsIds(userId, callback) {
    var query = User.findOne({_id: userId});

    query.exec(function(err, user) {
        if(err) {
            callback(err);
            return;
        }

        return callback(null, user.friendsIds);
    });
}

效果很好。该函数返回 friend 的 ID,我在异步调用的“two” block 中使用了它们。

mongoose4.3.7 升级到 4.7.8 后,它停止工作。我开始收到 Mongoose: mpromise (mongoose's default Promise Library) is deprecated, Plug in your own Promise Library 相反 警告,并且回调中不再返回 ids。

因此,我将 bluebird 包添加到项目中,并将其插入到 mongoose 中。现在警告消失了,但是回调中仍然没有返回 ids。

我还将async升级到最新版本,但也没有帮助。

为了使这项工作顺利进行,我还应该做些什么吗?

最佳答案

使用 Promise 的想法是不使用回调,并且您仍然在代码中使用回调。

假设您需要像 Bluebird 这样的

mongoose.Promise = require('bluebird');

您的函数现在应该如下所示:

function getFriendsIds(userId) {
    //This will now be a bluebird promise
    //that you can return
    return User.findOne({_id: userId}).exec()
        .then(function(user){
            //return the friendIds (this is wrapped in a promise and resolved)
            return user.friendsIds;
        });
}

该函数的返回值将是user.friendsIds的数组。利用 Promise 的链接可能性,您可以编写一个函数来获取每个 friend 的详细信息,并将其作为 friendDetails 数组返回。

function getFriendsDetails(friendIds) {
    //For each friendId in friendIds, get the details from another function
    //(Promise = require("bluebird") as well)
    return Promise.map(friendIds, function(friendId) {
        //You'll have to define the getDetailsOfFriend function
        return getDetailsOfFriend(friendId);
    });
}

简单地调用它为

getFriendsIds(123)
    .then(getFriendsDetails) //the resolved value from previous function will be passed as argument
    .then(function(friendDetails) {
        //friendDetails is an array of the details of each friend of the user with id 123
    })
    .catch(function(error){
       //Handle errors
    });
<小时/>

如果你想编写更少的代码,你可以让 bluebird promisify 像这样的 mongoose 函数

Promise.promisify(User.findOne)(123)
    .then(function(user){
        return user.friendsIds;
    })
    .then(getFriendsDetails)
    .then(function(friendDetails) {
        //Return or do something with the details
    })
    .catch(function(error){
        //Handle error
    });

关于node.js - Mongoose 升级后,异步不会在回调中返回数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41894360/

相关文章:

node.js - 如何在 mongodb 聚合项目阶段合并两个对象?

ruby-on-rails - 使用 Rails 提高性能以加载 3000 条记录?

javascript - 是否可以在 Java 或 JavaScript 中发出 HTTP (POST) 请求而不等待响应

asynchronous - F# 异步工作流/任务结合免费 monad

javascript - 在 Node.js 中,为什么使用 require 函数在模块之间变量相等?

javascript - NodeJS : understanding nonblocking/event queue/single thread

node.js - 正确安装 Node

node.js - Bower 未安装

mongodb - 在 $sort 聚合管道之后向文档添加字段,该管道使用 MongoDb 聚合将其索引包含在排序列表中

sockets - 单线程 NGINX 如何处理如此多的连接?