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

在以下功能中,创建 work 文档后,我保存了通过multer模块检索到的请求中的图像。当保存 image 文档时,我尝试更新通过推送图像的所有_id工作文档。

但是以某种方式,如果您看一下下面的代码并专注于 console.log ,那么第二个 console.log 会首先执行,尽管我创建图像时使用了 .then 。这也意味着我在最后几行代码中得到了过时的 work 文档。

文档说 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张图片。上面您在响应中看到 images 数组没有任何元素,而在mongo中保存了图片ID:

执行后保存的工作:

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

最终目标是用新创建的 work 进行响应,其中包含图像ID,因此我可以进一步填充 work的 images 数组文档和 image 文档中的 workId

如何使代码同步运行?

guojinfei 回答:为什么猫鼬在创建和更新文档时会异步运行?

问题在于:

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,并在一段时间后返回了第一个承诺的结果。

正确的方法是:

 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));                }

甚至更简单的方法是使用异步/等待。

本文链接:https://www.f2er.com/2641800.html

大家都在问