【问题标题】:Promises: return then() when action inside it is finished承诺:当里面的动作完成时返回 then()
【发布时间】:2018-12-20 00:41:51
【问题描述】:

我正在使用 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 完成移动图像时才会触发第二个?

谢谢!

【问题讨论】:

  • 我认为您在req.files.imgFile.mv(toRelative(req.body.img), function(err) { if (err) { throw new Error('Image saving failed'); } }); 中缺少第二个回调结果。
  • 在then里面放一个promise。
  • 您是否尝试过在第二个然后在 req.files.imgFile.mv 的回调中执行您尝试运行的代码?

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


【解决方案1】:

当你有一些基于回调而不是基于 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));
})

【讨论】:

  • 我现在在github docs 中看到它返回了一个承诺;这也是正确的吗?:.then(() => { if (!req.files) return; req.files.imgFile.mv(toRelative(req.body.img)).then(() => { return; }); })
  • 啊,原来如此,您最初将它用作回调。省略回调函数,您仍然需要 return .mv 返回的 Promise 才能正确链接,如编辑
  • 而且这个也可以写成return req.files ? req.files.imgFile.mv( toRelative(req.body.img) ) : true;吧?
  • 可以,但没必要。如果返回值不是 Promise(例如,如果返回 nothing,默认为 undefined),则下一个 .then 将立即运行。返回的true 表达式将不被使用。 if 可能更好。
猜你喜欢
  • 2016-03-09
  • 1970-01-01
  • 2013-06-15
  • 2020-11-20
  • 1970-01-01
  • 1970-01-01
  • 2020-04-27
  • 1970-01-01
  • 2017-08-19
相关资源
最近更新 更多