【问题标题】:Nodejs bluebird promise fails while processing image处理图像时Nodejs蓝鸟承诺失败
【发布时间】:2016-10-11 11:44:18
【问题描述】:
//Created a promise for each image size.
var promises = sizes.map(function (size) {
    return new Promise(function (resolve, reject) {
      var destinationDir = fileUtil.getAbsolutePathOfImage(destinationPath);
      fileUtil.createDirectoryIfNotExists(destinationDir);
      destinationDir += size.src;
      fileUtil.createDirectoryIfNotExists(destinationDir);
      //Resize the image.
      //console.log('imagefile : ' + JSON.stringify(imageFile));
      //console.log('destinationDir: ' + JSON.stringify(destinationDir));
//Called an imageUtil resize method to perform resize.
      imageUtil.resize(imageFile, destinationDir, size).then(data => {
        var fileName = destinationPath + size.src + '/' + data;
        resolve(imageUtil.createImageData(fileName, size.height, size.width));
      }).catch(err => {
        console.error(err);
        return reject(err);
      });
    });
  });

  Promise.all(promises)
    .then(savedImages => {
      console.log('saved Images are: ' + JSON.stringify(savedImages));
      return res.status(200).json(savedImages);
    }).catch(err => {
      console.log('i am here' + JSON.stringify(err.message));
      return res.status(400).json(JSON.stringify(err.message));
    });



---------------------Resize method of imageutil---------------

var Promise = require('bluebird'),
  gm = require('gm'),
  path = require('path'),
  fs = require('fs');

Promise.promisifyAll(gm.prototype);

module.exports = {

  resize(imageFile, destinationPath, size){
    if (!imageFile || !destinationPath || !size) {
      return;
    }
    return new Promise(function (resolve, reject) {
      // If we just passed callback directly, errors would be fatal
      var fileName = fileUtil.getFileName(imageFile);
      //console.log('sourceFile : ' + JSON.stringify(imageFile));
      //console.log('saveDirectory : ' + JSON.stringify(destinationPath));
      //console.log('fileName is :' + fileName);
      //Create a write stream.
      var writeStream = fs.createWriteStream(destinationPath + '/' + fileName);
      //console.log('Saving at location: ' + writeStream.path);
      gm(imageFile)
        .resize(size.width, size.height, '^')
        .gravity('Center')
        .crop(size.width, size.height)
        .writeAsync(writeStream.path, function (err) {
          if (err) {
            var error = 'Error while creating image of resolution : ' + size.width + 'x' + size.height + '.';
            console.error(JSON.stringify(error));
            return reject(new Error(error));
          }
        });
      resolve(fileName);
    });
  }

};

*似乎一切正常,它创建了四个损坏的图像文件,后来给了我错误,但请求处理成功。我的图像处理的控制台输出如下:

saved Images are: [{"src":"/uploads/300/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"200","width":"300"},{"src":"/uploads/120/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"120","width":"120"},{"src":"/uploads/48/fhjXFLgqq59F91uFK_2h8GiS.jpg","height":"48","width":"48"}]

POST /api/upload/image/ 200 51.790 毫秒 - 241 “创建分辨率图像时出错:120x120。” “创建分辨率图像时出错:48x48。” “创建分辨率图像时出错:300x200。”*

【问题讨论】:

  • 您能否尝试将console.error(JSON.stringify(error)); 替换为console.error(JSON.stringify(err)); 并发布它打印出来的内容?
  • 嘿马丁,它被迭代三次。所以,输出是 {"code":1,"signal":null} {"code":1,"signal":null} {"code":1,"signal":null}
  • 我的猜测是它无法读取原始图像。您能否将console.log(imageFile) 放在gm(imageFile) 之前并发布它现在所说的内容?
  • 是的,它无法读取原始图像,但它仍然会生成三个损坏的图像文件,并向我发送响应状态 200 及其路径而不是错误。 :(
  • 我认为@yurytarabenko 找到了问题所在。另一个问题是您正在向 gm 发送一个 json 对象 imageFile 。也许尝试使用gm(fileName) 而不是gm(imageFile)

标签: node.js promise bluebird graphicsmagick gm


【解决方案1】:

由于您已经在使用promisifyAll,因此您不需要(和should not)使用Promise 构造函数。 write<em>Async</em> 已经返回了一个承诺 - 如果你不传递回调,因为这是 Bluebird 能够在正确的位置传递回调本身的要求。

你应该使用

module.exports = {
  resize(imageFile, destinationPath, size){
    if (!imageFile || !destinationPath || !size) {
      return Promise.reject(new Error("missing arguments"));
    }
    var fileName = fileUtil.getFileName(imageFile);
    //console.log('sourceFile : ' + JSON.stringify(imageFile));
    //console.log('saveDirectory : ' + JSON.stringify(destinationPath));
    //console.log('fileName is :' + fileName);
    //Create a write stream.
    var writeStream = fs.createWriteStream(destinationPath + '/' + fileName);
    //console.log('Saving at location: ' + writeStream.path);
    var promise = gm(imageFile)
      .resize(size.width, size.height, '^')
      .gravity('Center')
      .crop(size.width, size.height)
      .writeAsync(writeStream.path);
    return promise.then(function() {
      return filename;
    }, function (err) {
      var error = 'Error while creating image of resolution : ' + size.width + 'x' + size.height + '.';
      console.error(error, err);
      throw new Error(error);
    });
  }
};

同样,您不应在对 resize 的调用中使用 Promise 构造函数反模式 - 它已经返回了一个承诺:

var promises = sizes.map(function (size) {
  var destinationDir = fileUtil.getAbsolutePathOfImage(destinationPath);
  fileUtil.createDirectoryIfNotExists(destinationDir);
  destinationDir += size.src;
  fileUtil.createDirectoryIfNotExists(destinationDir);
  //Resize the image.
  //console.log('imagefile : ' + JSON.stringify(imageFile));
  //console.log('destinationDir: ' + JSON.stringify(destinationDir));
  return imageUtil.resize(imageFile, destinationDir, size)
//^^^^^^
  .then(data => {
    var fileName = destinationPath + size.src + '/' + data;
    return imageUtil.createImageData(fileName, size.height, size.width));
  }, err => {
    console.error(err);
    throw err;
  });
});

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-13
    • 2014-11-06
    • 2015-09-06
    相关资源
    最近更新 更多