Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/477.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/33.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将节点gm与承诺和缓冲区一起使用_Javascript_Node.js_Promise_Gm - Fatal编程技术网

Javascript 将节点gm与承诺和缓冲区一起使用

Javascript 将节点gm与承诺和缓冲区一起使用,javascript,node.js,promise,gm,Javascript,Node.js,Promise,Gm,我一直在尝试将转基因技术用于蓝鸟,如下所示: 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(...) 但是,当我尝试这样的

我一直在尝试将转基因技术用于蓝鸟,如下所示:

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(...)
但是,当我尝试这样的事情时:

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)


如果我不使用Promissions,它就可以正常工作。

这并不是你应该如何使用
gm
模块,因为它的设计目的是提供一个工厂
gm()
和许多可级联的变异函数,如
.resize()

Bluebird的
.promisifyAll()
仅适用于接受回调的函数,而大多数
gm
的函数不接受回调

如果您希望使用带有承诺的
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
要复杂得多

下面是一种使用事件状态机执行所需操作的方法

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'); 
或者如果你真的,真的想用承诺

const writer = function (img) {
  return new Promise( (resolve, reject) => {
    img.write(output_path,err => {
      if(err) {
        reject(err);
        return;
      }
      resolve(true);
    });
  });
};

const reader = function (input_path) {
  return new Promise( (resolve,reject) => { 
    let img;
    try {
      img = gm(input_path);
    }
    catch (err) {
      reject(err);
      return;
    }
    resolve(img);
  });
};

reader('./image.jpg')
  .then( img => { return img.resize(100,100) }) // the return here is for illustration only
  .then( img => img.crop(2,2,50,50))            // since this does exactly the same thing with less typing!
  .then( writer )
  .then( res => console.log('complete'))
  .catch( err => console.error(err.toString()));

同样,更多的输入和复杂性都是为了使用最新的“闪亮”的东西

在这一点上,只使用设计好的模块似乎要容易得多。实际上,我想在一个图像缓冲区上执行10个以上的操作,所以我考虑使用
Promise.all([gmPromises])
。在这种情况下,使用承诺真的让一切变得简单多了。是的……但是通用汽车并不是为了支持承诺而写的,所以你需要“找到另一种方式”。)在
新承诺
回调中使用
try
/
catch
是毫无意义的。@RobRaisch否决不是因为代码不够简洁,而是因为它不起作用并且暗示了错误的功能。异步函数(应该)永远不会同步抛出,因此没有必要使用
try
/
catch
。只有当回调出现错误时,您才需要调用
reject
,但是您没有这样做,而是
throw
它(导致
uncaughtException
)。在您的帖子中唯一一个好的提示是
writer
promisifyAll
创建一个
.toBufferAsync()
函数,该函数将返回承诺。您需要调用该函数,而不是
.toBuffer()
。您的
promisify
方法不起作用,因为
toBuffer
函数对实例起作用。@Bergi下次您可能希望在注释之前实际尝试该代码,然后建议使用
.toBufferAsync()由于我在回答中提供的原因,
不起作用。@RobRaisch当然(考虑到
toBuffer
接受回调),我看不出你的回答中有任何理由不起作用?@Bergi,也许你想提供一个使用蓝鸟
promisifyAll()
的工作示例?