将节点gm与promises和buffers一起使用

时间:2016-11-25 16:02:37

标签: javascript node.js promise gm

我一直试图像这样使用gm和Bluebird:

var gm = require('gm');
var bluebird = require('bluebird');
gm = bluebird.promisifyAll(gm);

但是,当我尝试这样的事情时:

gm(req.file.buffer)
     .crop(tWidth, tHeight, tWidth/2, tHeight/2)
     .gravity('Center')
     .toBuffer()
  .then(...)

我收到此错误:

  

gm()。toBuffer()需要回调。

如果我只宣传缓冲方法:

bluebird.promisify(gm(req.file.buffer)
        .crop(tWidth, tHeight, tWidth/2, tHeight/2)
        .gravity('Center')
        .toBuffer)()
        .then(buff => {...})

我收到此错误:

  

TypeError:this.stream不是函数   上午6:36:21 web.1 |在toBuffer(/Users/danielrvt/IdeaProjects/twe-backend/node_modules/gm/lib/command.js:162:17)

如果我不使用承诺,它就可以了。

1 个答案:

答案 0 :(得分:0)

这并不是你应该如何使用gm模块,因为它旨在提供工厂gm()和许多可级联的mutator函数,如{{1 }}。

Bluebird的.resize()仅适用于接受回调的功能,而大部分.promisifyAll()的功能都没有。

如果您希望将gm与承诺一起使用,则您需要" promisify"把它作为

包裹起来,你自己
gm

之后,你可以

function mutateAndSave() {
  return new Promise( function(resolve,reject) {
    try {
      gm(image)
        .doSomething()
        .write(outputPath, function(err) {
          if(err) {
            throw(err);
          }
          resolve();
        });
    }
    catch (err) {
      reject(err);
    }
  });
}

更新

以下两种方法可以做你想做的事,但是......

您会注意到两者都比仅仅使用mutateAndSave() .then(...) .catch(...); 更复杂。 ;)

以下是使用事件状态机执行所需操作的方法。

gm

或者,如果你真的,真的想要使用Promises ......

const gm = requre('gm');
const EventEmitter = require('events');
const input_path = './image.jpg'
const output_path = './newimage.jpg';
const worker = new EventEmitter(); // create an event worker

// define the worker states - note: NO error checking! Muy mal! 
const event_states={
  start:()       => worker.emit('resize',gm(input_path)),       // creates a new gm image instance
  resize:(img)   => worker.emit('crop', img.resize(100,100)),   // resizes the image
  crop:(img)     => worker.emit('write', img.crop(2,2,50,50)),  // crops it
  write:(img)    => {                                           // and writes it to the filesystem
    img.write(output_path, err => {
      if(err) {
        worker.emit('error',err);
        return;
      }
      worker.emit('complete');
    });
  },
  error: (err)  => console.error(err.toString()),             // report error
  complete: ()  => console.log('complete')                    // alert on completion
};

// add the states to the worker as event handlers
Object.keys(event_states).forEach(k => worker.on(k, event_states[k]));

// and fire it up...
worker.emit('start'); 

同样,更多的打字和复杂性都可以使用最新的"闪亮的"事情。 ;)