为什么 mongoose 运行 在创建和更新文档时异步?
Why does mongoose run asynchronously when creating and updating a document?
在下面的函数中,在创建 work 文档后,我保存了通过 multer module.When 检索到的请求中的图像,保存了 image 文档 我尝试通过推送图像的所有 _id
来更新 work 文档。
但是不知何故,如果你看一下下面的代码并关注 console.logs,第二个 console.log 首先被执行,尽管我在创建 images.That 时使用了 .then 也意味着我得到了一个过时的 work 关于最后几行代码的文档。
文档说 Model.create() returns 一个 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));
}
这是发布 work 文档后的控制台:
cmd 执行后:
并且有响应:
执行后响应:
有 2 张图像 added.Above 您在响应中看到 images 数组没有任何元素,而在 mongo 中图像 ID 是已保存:
执行后保存的工作:
最终目标是响应新创建的 work,其中包含图像 ID,因此我可以进一步填充 images work 文档的数组和 image 文档中的 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)); }
更简单的方法是使用异步/等待。
在下面的函数中,在创建 work 文档后,我保存了通过 multer module.When 检索到的请求中的图像,保存了 image 文档 我尝试通过推送图像的所有 _id
来更新 work 文档。
但是不知何故,如果你看一下下面的代码并关注 console.logs,第二个 console.log 首先被执行,尽管我在创建 images.That 时使用了 .then 也意味着我得到了一个过时的 work 关于最后几行代码的文档。
文档说 Model.create() returns 一个 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));
}
这是发布 work 文档后的控制台:
cmd 执行后:
并且有响应:
执行后响应:
有 2 张图像 added.Above 您在响应中看到 images 数组没有任何元素,而在 mongo 中图像 ID 是已保存:
执行后保存的工作:
最终目标是响应新创建的 work,其中包含图像 ID,因此我可以进一步填充 images work 文档的数组和 image 文档中的 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)); }
更简单的方法是使用异步/等待。