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" 块中使用了它们。
将 mongoose
从 4.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
});
在我的项目中,我使用 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" 块中使用了它们。
将 mongoose
从 4.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
});