承诺:完成其中的操作后返回then()

时间:2018-07-11 21:39:01

标签: javascript node.js express promise sequelize.js

我正在使用React-Redux-Express,并且尝试使用express-fileupload上传图像。这是我在Express服务器中上传图像的逻辑:

在我的Express路线中,我使用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));
        });
});

问题在于,在then方法完成图像移动之前,最后一个req.files.imgFile.mv被触发,因此React输入组件无法在前端找到它。

有人知道我怎么能在第一个then内创建一个承诺,所以只有当req.files.imgFile.mv完成图像移动后,第二个才被触发?

谢谢!

1 个答案:

答案 0 :(得分:6)

当您有基于回调而不是基于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(本身返回Promise会更容易:

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