Nodejs bluebird promise fails while processing image

天涯浪子 提交于 2020-01-04 08:06:20

问题


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

};

*It seems like everything went correct and it creates four image file which is corrupted and gave me error later on but request processed succesfully. Console output of my image processing are as follows:

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 ms - 241 "Error while creating image of resolution : 120x120." "Error while creating image of resolution : 48x48." "Error while creating image of resolution : 300x200."*


回答1:


Since you are already using promisifyAll, you don't need to (and should not) use the Promise constructor. writeAsync already returns a promise - if you don't pass a callback, as that's the requirement for Bluebird being able to pass the callback itself in the right position.

You should be using

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

Similarly, you shouldn't use the Promise constructor antipattern in the call to resize - it already returns a 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;
  });
});


来源:https://stackoverflow.com/questions/39976502/nodejs-bluebird-promise-fails-while-processing-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!