javascript - Node.js/通用 : Promises with asynchronous calls

标签 javascript node.js asynchronous promise gm

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

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

但是对于切换情况 resize,我需要知道图像的尺寸,我通过 size() 获得了它。但这是一个异步调用。 使用此 gmStream 不用于开关下方显示的 stream()。但是在这个 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)
        })
      })
  })
}

最佳答案

您可能希望将 Promises 链接在一起以完成您所追求的目标。如果你将 switch case 中的逻辑分解为返回 Promise 的函数,你可能会得到类似下面的东西(免责声明:我从未使用过 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)
        })
      })
    })
  })
}

关于javascript - Node.js/通用 : Promises with asynchronous calls,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46115781/

相关文章:

javascript - 计算嵌套 Javascript 对象的重复属性值

javascript - 使用相机源从视频元素中提取快照

api - 如何拦截 node.js 快速请求

node.js - AWS-EB- Node -错误 : Cannot find module '../'

javascript - 等待多个 for-each 语句完成

javascript - 在函数中使用 fetch() 导致 "output not defined"

javascript - D3 DateTime 解析器考虑时区

javascript - momentjs 如何处理以月或年为单位的加法或减法

node.js - Multer 返回空响应

mongodb - JS Node 异步处理事件