【问题标题】:Promise resolve fires before task is complete承诺在任务完成之前解决火灾
【发布时间】:2018-01-21 23:23:06
【问题描述】:

我正在使用 promise 函数和 Jimp 调整图像大小,将其保存在文件夹中,然后返回新调整大小图像的路径。

但是,resizeWidth() 中的 resolve() 函数在 image.resize().write() 完成之前被触发,这意味着我的应用程序由于找不到新文件而崩溃。

任何帮助将不胜感激。

const fs = require('fs');
const path = require('path');
const jimp = require('jimp');

const resizeWidth = function(file, width) {
  return new Promise((resolve, reject) => {
    jimp.read(path.join(__dirname, '..', 'assets', 'images', file), (err, image) => {
      if (err) reject(err);
      const xSize = parseInt(width);
      image.resize(xSize, jimp.AUTO)
        .write(path.join(__dirname, '..', 'assets', 'images', 'tmp', file));
      resolve(path.join(__dirname, '..', 'assets', 'images', 'tmp', file));
    });
  });
};

module.exports = function(server) {
  server.get('/images/:name/:width', (req, res) => {
    resizeWidth(req.params.name, req.params.width)
      .then(() => {
        fs.readFile(path.join(__dirname, '..', 'assets', 'images', 'tmp', req.params.name),
          (err, newData) => {
            if (err) throw err;
            res.sendRaw(200, newData, {
              'Content-Length': Buffer.byteLength(newData)
            });
            res.end();
          });
      })
      .catch((err) => {
        console.log(err);
      });
  });
};

【问题讨论】:

  • 你可以做path.join(__dirname, '../assets/images/tmp', file),请注意。还要注意throw err 会杀死你的服务器;我建议使用fs.readFile 的承诺版本。
  • @Ryan,是的,这只是一个初步测试,看看 jimp 是否符合项目要求 - 重构会处理你提到的事情。
  • 哦,绝对不要在没有验证或转换 req.params.name 的情况下读取和响应 path.join(…, 'tmp', req.params.name) 的内容,除非您希望客户端具有读/写访问权限(取决于权限 - 两者都同样糟糕) 使用?name=../../sensitive-config 复制到系统上的任何文件。我建议使用 UUID 或哈希。

标签: node.js promise restify


【解决方案1】:

write 是异步函数,因此在 write 函数完成之前调用 resolve。使用回调确保顺序

jimp.read(path.join(__dirname, '..', 'assets', 'images', file), (err, image) => {
  if (err) reject(err);
  const xSize = parseInt(width);
  image.resize(xSize, jimp.AUTO)
    .write(path.join(__dirname, '..', 'assets', 'images', 'tmp', file), () => {
       resolve(path.join(__dirname, '..', 'assets', 'images', 'tmp', file));
    });
});

【讨论】:

  • 非常简单的解决方案。谢谢!
  • @BrianEmilius 如果可行,请接受此答案。如果没有,请评论这个答案,另一个问题发生了。我会尽力帮忙的。
猜你喜欢
  • 1970-01-01
  • 2015-07-18
  • 2015-06-24
  • 2019-05-29
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 2019-04-13
  • 2021-08-11
相关资源
最近更新 更多