首页 > 解决方案 > Promises: return then() when action inside it is finished

问题描述

I am using React-Redux-Express, and I'm trying to upload an image with express-fileupload. Here is my logic for uploading images in my Express server:

In my Express route I do this with Sequelize

router.put('/:id', function(req, res, next) {
    models.Projects.update(
        {
            title: req.body.title,
            img: req.body.img,
            description: req.body.description,
        },
        {
            returning: true,
            plain: true,
            where: {
                id: req.params.id,
            },
        }
    )
        .then(() => { 
            if (req.files) {
                req.files.imgFile.mv(toRelative(req.body.img), function(err) { 
                    if (err) {
                        throw new Error('Image saving failed');
                    }
                });
            }
        })
        .then(() => { 
            models.Projects.findById(req.params.id).then((result) => {
                return res.send({
                    Project: result,
                });
            });
        })
        .catch((error) => {
            return res.send(String(error));
        });
});

The problem is that the last then is triggered before req.files.imgFile.mv method is finished moving the image, so the React input component can't find it in the frontend.

Does anyone know how can I create a promise inside the first then, so only when req.files.imgFile.mv is finished moving the image the second is triggered?

Thanks!

标签: javascriptnode.jsexpresspromisesequelize.js

解决方案


当你有一些基于回调而不是基于 Promise 的东西时,一般的想法是显式地构造一个 Promise 以便它可以在更大的 Promise 链中使用:

.then(() => { 
  if (!req.files) return; // resolve immediately if there are no files
  return new Promise((resolve, reject) => {
    req.files.imgFile.mv(toRelative(req.body.img), function(err) { 
      if (err) return reject('Image saving failed');
      resolve();
    });
  });
})

但是,在这种情况下,省略回调函数来强制req.files.imgFile.mv(返回 aPromise本身会更容易:

.then(() => { 
  // if there are files, then the outer Promise chain will wait
  // for the returned Promise to resolve before continuing with the next .then:
  if (req.files) return req.files.imgFile.mv(toRelative(req.body.img));
})

推荐阅读