我有2个集合(User和Offer),我使用异步进行一系列操作,但最后一个文档没有被删除。
async.series([
function (callback) {
User.findOne({_id: req.user._id}, function (err, result) {
if (err) {
return callback(err);
}
user = result;
callback();
});
},
function (callback) {
Offer.find({_owner: user._id}, function (err, offers) {
if (err) {
return callback(err);
}
var i = offers.length;
while (i--) {
var offer = offers[i];
Offer.remove(offer, function (err) {
return callback(err);
});
}
callback();
});
},
function (callback) {
User.remove(user, function (err) {
if (err) {
return callback(err);
}
});
callback();
}
], function (err) {
if (err) {
return res.status(503).json({message: err});
}
res.status(200).json({message: 'User and offers successfully deleted'});
});
我打开了 mongoose 调试,发现该用户的 8 个文档被删除(如预期)。消息示例:
Mongoose: users.remove({ active: true, role: 'user', favoredOffers: [],
salt: 'qIADYcMS3SiAuF3M007E9g==', hashedPassword: '**', emailVerified: true,
name: 'Test', email: 'test1@test.com', emailVerificationToken: '***',
updatedAt: new Date("Mon, 21 Sep 2015 00:52:58 GMT"),
createdAt: new Date("Mon, 21 Sep 2015 00:52:58 GMT"),
_id: ObjectId("55ff54ea1d6201ff42ea0045") }) {
safe: { w: 'majority', wtimeout: 10000 } }
当我运行测试时,结果是,这个文档仍然存在。起初,我认为我的测试运行得太快(async.waterfall),但后来我切换到 async.series,行为仍然存在,当我查看 test-db 时,文档仍然存在。
测试代码:
it.only('should allow deleting my account and all my offers if my password was right', function (done) {
async.series([function (callback) {
login(server, server.delete('*url*'), 'test@test.com', 'testpwd1', function (server) {
server
.send({password: 'testpwd1'})
.expect(200)
.end(callback);
});
}, function (callback) {
User.findOne({email: 'test1@test.com'}, function (err, user) {
callback(user ? new Error('user was still found in mongo') : null); //misuse not found user as 'error'-object
});
}, function (callback) {
Offer.find({_owner: user1._id}, function (err, offers) {
expect(offers).to.have.length(0);
callback();
});
}], done);
});
结果:未捕获断言错误:预期 [ Array(1) ] 的长度为 0,但得到了 1
我是否遗漏了什么或者我不理解 mongdb 的行为。
最佳答案
虽然这些操作是按照 async.series
中分割的操作串行调用的,这里的问题是while
循环不是异步控制的,因此在所有删除完成之前会调用移动到下一个阶段的回调。
您可以使用 async.whilst
控制来自 .remove()
的回调操作,但这太过分了,因为您实际上应该直接向 .remove()
发出“查询”而不是尝试使用 .find()
返回的列表:
async.series(
[
function (callback) {
Offer.remove({ "_owner": req.user._id}, callback);
},
function (callback) {
User.remove({ "_id": req.user._id },callback);
}
],
function (err,results) {
if (err) {
res.status(503).json({message: err});
} else {
if ( Array.sum(results) == 0 ) {
res.status(404).json({message: 'User not found'});
} else {
res.status(200).json({message: 'User and offers successfully deleted'});
}
}
}
);
当然,如果删除操作的结果没有删除任何内容,那么您就知道输入与用户不匹配。
异步库允许回调传递,因此您无需控制每个阶段。任何错误以及每个阶段的结果都会立即进入结束 block 。另请参阅 parallel
相反,在这种情况下,一个阶段不依赖于另一个阶段先完成。
关于javascript - mongoose remove 不会删除所有文档,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32686189/