2017-09-08 18 views
1

私はgmを使用して、nodeJSアプリケーション内のいくつかの画像を操作しています。これは私の機能がどのように見えるかです。NodeJS/gm:非同期呼び出しで約束する

ご覧のとおり、いくつかの操作(この例では回転)用のスイッチがあります。 gmStreamが作成され、スイッチ.stream()pipe()が使用されます。 これまでのところすべて問題ありません。

スイッチケースresizeの場合は、画像の寸法を知る必要があります。これはsize()で取得します。しかし、これは非同期呼び出しです。 このgmStreamはスイッチの下に表示されているstream()には使用されません。しかし、あなたは後にしているものを達成するために一緒にチェーンを約束したいことがあります...

function manipulate (method, param) { 
    return new Promise(function (resolve, reject) { 

    // Configure GridFS (gridfs-stream) 
    const gfs = Grid(
     MongoInternals.defaultRemoteCollectionDriver().mongo.db, 
     MongoInternals.NpmModule 
    ) 

    switch (method) { 
     case 'rotate': 
     gmStream = gm(readStream) 
      .rotate('#ffffff', param.rotate) 
     break 

     // ... some more cases ... 

     case 'resize': 
     gmStream = gm(readStream) 
      .size(function (err, size) { 
      if (!err && size.width >= 1000 && size.height >= 1000) { 
       gmStream.resize('1000').stream().pipe(writeStream) // <-- should use the stream call below, as there has to be done some DB manipulation... 
      } 
      }) 
     break 
    } 

    // resize case should also use this part... 
    gmStream 
     .stream(function (err, stdout, stderr) { 
     gfs.findOne({ _id: sourceId }, function (err, file) { 
      const writeStream = gfs.createWriteStream({ 
      metadata: { } 
      }) 

      writeStream.on('close', 
      function (newFile) { 
       resolve(newFile) 
      } 
     ) 

      stdout.pipe(writeStream) 
     }) 
     }) 
    }) 
} 

答えて

2

がこのstream()にいくつかのより多くのDBのものをやったので、私は同じことを使用する必要があります。あなたのスイッチのロジックをプロミスを返す関数に分解した場合、以下のようなものを得ることができます(免責:私はgmを使用したことは一度もなく、そのAPIに慣れていません)。

function rotate (readStream, rotate) { 
    return new Promise(function (resolve, reject) { 
    resolve(gm(readStream).rotate('#ffffff', param.rotate)) 
    }) 
} 


function resize (readStream, writeStream) { 
    return new Promise(function (resolve, reject) { 
    var gmStream = gm(readStream) 

    gmStream.size(function (err, size) { 
     if (err) { 
     return reject(err) 
     } 

     if (size.width >= 1000 && size.height >= 1000) { 
     gmStream.resize('1000').stream().pipe(writeStream) 
     resolve(gmStream) 
     } 
    }) 
    }) 
} 


function handleManipulation (args) { 
    return new Promise(function (resolve, reject) { 
    // This will be a Promise for the base gmStream object to work with 
    var gmStream; 

    // Not sure where this comes from, so here's a placeholder 
    var readStream = ...; 

    // You were doing this for every case, so I don't think putting it here 
    // will cause you any grief, but it's a resource to clean up if the 
    // Promise gets rejected, so keep that in mind 
    const writeStream = gfs.createWriteStream({ 
     metadata: { } 
    }) 

    // Figure out which method to create a Promise'd object for 
    switch (args.method) { 
     case 'rotate': 
     gmStream = rotate(readStream, ...) // I'm not sure what the value of 
              // the `rotate` argument should be 
     break 
     case 'resize': 
     gmStream = resize(readStream, writeStream) 
     break 
    } 

    // We wait for the gmStream Promise to resolve before proceeding. 
    gmSteam.then(function (stream) { 
     stream.stream(function (err, stdout, stderr) { 
     if (err) { 
      return reject(err) 
     } 

     gfs.findOne({ _id: sourceId }, function (err, file) { 
      if (err) { 
      return reject(err) 
      } 

      writeStream.on('close', 
      function (newFile) { 
       resolve(newFile) 
      } 
     ) 

      stdout.pipe(writeStream) 
     }) 
     }) 
    }) 
    }) 
} 
関連する問題