我正在调试我想要一个接一个地执行的Mongoose查询的一大块,以避免不一致。经过大量的试验,错误和测试,我终于偶然发现了一个似乎有效的解决方案。
在一个查询中,我包含一个查询,在另一个查询中,我跳过包括回调函数。我所指的回调可以在Model.findByIdAndUpdate
语句的语法中看到。
Model.findByIdAndUpdate(id, [update], [options], [***callback***])
具有回调功能的那个完美地执行,并且没有执行回调功能的那个没有执行。它封装在一个返回mongoose promsise的函数中。
这是Robomongo中第一个使用模式的查询,它增加了一个'组织者'成功:
function addUserToHackathonOrganisers(userId, hackathonId) {
return Hackathon.findOneAndUpdate(
{hackathonId: hackathonId},
{$addToSet: {organisers: userId.toString()}},
{new: true}
);
}
现在,这是有效的查询(回调中)。在附加的图像中,您可以看到组织者数组[1] ,它表示已更新。
function addUserToHackathonOrganisers(userId, hackathonId) {
return Hackathon.findOneAndUpdate(
{hackathonId: hackathonId},
{$addToSet: {organisers: userId.toString()}},
{new: true},
function (err) {
if (err) {
console.log(err);
}
}
);
}
我一无所知为什么会这样。有什么想法吗?
答案 0 :(得分:3)
这是因为没有回调选项的 findOneAndUpdate()
方法会返回Query
,它不会执行但会执行带有回调的方法,因此您会看到更新回调,没有没有。
来自docs:
A.findOneAndUpdate(conditions, update, options, callback) // executes
A.findOneAndUpdate(conditions, update, options) // returns Query
A.findOneAndUpdate(conditions, update, callback) // executes
A.findOneAndUpdate(conditions, update) // returns Query
A.findOneAndUpdate() // returns Query
如果您已将该功能写为
function addUserToHackathonOrganisers(userId, hackathonId) {
return Hackathon.findOneAndUpdate(
{hackathonId: hackathonId},
{$addToSet: {organisers: userId.toString()}},
{new: true}
).exec(); // chaining exec() to a Query returns a Promise
}
然后当你调用它时,它会执行并返回一个promise,例如
var promise = addUserToHackathonOrganisers(userId, hackathonId);
promise.then(function(addedUser){
console.log(addedUser); // shows the updated user
});
要在评论中解决您的follow-up question,请使用promise的then()
方法
promise.then(function(addedUser){
console.log(addedUser); // shows the updated user
});
与 findOneAndUpdate()
选项中的回调相同,除了不是两个参数,promise使用promise {{1}中捕获的错误参数分别处理参数方法:
catch()
有关详细信息,请参阅文档here。