【问题标题】:NodeJS/gm: Promises with asynchronous callsNodeJS/gm:带有异步调用的 Promise
【发布时间】:2017-09-09 22:55:17
【问题描述】:

我正在使用gm 来处理我的nodeJS 应用程序中的一些图像。这就是我的函数的样子。

如您所见,有一个用于某些操作的开关(在此示例中:旋转)。 gmStream 被创建并且在开关 .stream()pipe() 之后将被使用。 到目前为止一切都很好。

但对于开关盒resize,我需要知道图像的尺寸,我确实通过size() 获得。但这是一个异步调用。 有了这个gmStream 不用于开关下方显示的stream()。但是这个stream()会做更多的DB东西,所以我需要使用同样的东西......

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

【问题讨论】:

    标签: javascript node.js asynchronous promise gm


    【解决方案1】:

    您可能希望将 Promise 链接在一起以完成您所追求的目标。如果您将 switch 案例中的逻辑分解为 Promise-returning 函数,您可能可以获得类似以下的工作(免责声明:我从未使用过 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)
            })
          })
        })
      })
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-02-08
      • 2017-01-09
      • 1970-01-01
      • 1970-01-01
      • 2017-08-24
      • 2020-05-31
      • 1970-01-01
      • 2013-10-23
      相关资源
      最近更新 更多