async 在 mongoose 升级后回调中没有 return 数据

async doesn't return data in callback after mongoose upgrade

在我的项目中,我使用 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);
    });
}

效果很好。该函数返回了朋友的 ID,我在异步调用的 "two" 块中使用了它们。

mongoose4.3.7 升级到 4.7.8 后,它停止工作了。我开始收到 Mongoose: mpromise (mongoose's default promise library) is deprecated, plug in your own promise library instead 警告,回调中不再返回 ID。

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

我也升级了async到最新版本,但也没有用。

为了完成这项工作,我还应该做些什么吗?

使用 promises 的想法是不使用回调,而您仍在代码中使用回调。

假设你需要像

这样的蓝鸟

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

函数的 returning 值将是 user.friendsIds 的数组。利用 promises 的链接可能性,您可以编写一个函数来获取每个朋友的详细信息,并且 return 作为 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
    });