繁体   English   中英

为什么 mongoose 在创建和更新文档时异步运行?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM