[英]Why does mongoose run asynchronously when creating and updating a document?
在以下函数中,创建工作文档后,我保存了通过 multer 模块检索到的请求中的图像。保存图像文档时,我尝试通过推送图像的所有_id
来更新工作文档。
但不知何故,如果你看一下下面的代码并关注console.log s,第二个console.log将首先执行,尽管我在创建图像时使用了.then 。这也意味着我得到了一个过时的工作文档的最后几行代码。
文档说Model.create()返回一个Promise ,这意味着如果我使用.then() (如果我没记错的话)它应该同步运行。 但在我的函数中情况并非如此:
function addToDB(req, res, model) { let imagesToAdd = []; Works.create(model) .then(work => { req.files.forEach(image => { let path = image.path.split('').map(char => char === '\\\\' ? '/' : char).join(''); let imageObj = { fileName: image.filename, mimeType: image.mimetype, imageURL: `${req.baseURL}/${path}`, workId: work._id }; imagesToAdd.push(imageObj); }); Images.create(imagesToAdd) .then(createdImages => { let imageIds = []; createdImages.forEach(image => { console.log(image._id); imageIds.push(image._id); }); Works.updateMany({_id: work._id}, {$push: {images: {$each: imageIds}}}).catch(err => handleError(err)); }) .catch(err => handleError(err)); console.log('>'+work._id); return work._id; }) .then(workId => { Works.findById(workId) .then(foundWork => { res.json(foundWork); }) .catch(err => handleError(err)); }) .catch(err => handleError(err)); }
这是发布工作文档后的控制台:
执行后cmd:
有回应:
执行后响应:
添加了 2 个图像。在响应中您看到图像数组没有任何元素,而在 mongo 中保存了图像 ID:
执行后保存的工作:
最终的目标是要与新创建的工作,这包括了图像的IDS响应,这样我就可以进一步填充图像文档中的工作文档和workId的图像阵列。
如何让代码同步运行?
问题在于:
Images.create(imagesToAdd)
.then(createdImages => {
let imageIds = [];
createdImages.forEach(image => {
console.log(image._id);
imageIds.push(image._id);
});
Works.updateMany({_id: work._id}, {$push: {images: {$each: imageIds}}}).catch(err => handleError(err));
})
设置为异步运行,然后:
console.log('>'+work._id);
return work._id;
执行后,您转到下一个then
,一段时间后返回第一个 promise 的结果。
正确的方法是:
function addToDB(req, res, model) {
let imagesToAdd = [];
Works.create(model)
.then(work => {
// Populate imagesToAdd
req.files.forEach(image => {
let path = image.path.split('').map(char => char === '\\' ? '/' : char).join('');
let imageObj = {
fileName: image.filename,
mimeType: image.mimetype,
imageURL: `${req.baseURL}/${path}`,
workId: work._id
};
imagesToAdd.push(imageObj);
});
Images.create(imagesToAdd)
.then(createdImages => {
// images have been created
let imageIds = [];
createdImages.forEach(image => {
console.log(image._id);
imageIds.push(image._id);
});
// imageIds has been populated
Works.updateMany({_id: work._id}, {$push: {images: {$each: imageIds}}})
.then(() => {
// After update is finished, findById
Works.findById( work._id )
.then( foundWork => {
// Return the work after it has been updated with images
res.json( foundWork );
} )
.catch( err => handleError( err ) );
})
.catch(err => handleError(err));
})
.catch(err => handleError(err));
})
.catch(err => handleError(err)); }
更简单的方法是使用 async / await。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.