Javascript NodeJS/gm:异步调用的承诺
我正在使用Javascript NodeJS/gm:异步调用的承诺,javascript,node.js,asynchronous,promise,gm,Javascript,Node.js,Asynchronous,Promise,Gm,我正在使用gm操作我的nodeJS应用程序中的一些图像。这就是我的函数的样子 如您所见,有一个开关用于某些操作(在本例中为旋转)gmStream被创建,并且在开关之后将使用.stream()和pipe()。 到目前为止一切都很好 但是对于开关盒resize,我需要知道图像的尺寸,这是通过size()获得的。但这是一个异步调用。 使用此gmStream不会用于开关下方显示的stream()。但是在这个流()中会有更多的DB内容,所以我需要使用相同的东西 function manipulate (m
gm
操作我的nodeJS应用程序中的一些图像。这就是我的函数的样子
如您所见,有一个开关用于某些操作(在本例中为旋转)gmStream
被创建,并且在开关之后将使用.stream()
和pipe()
。
到目前为止一切都很好
但是对于开关盒resize
,我需要知道图像的尺寸,这是通过size()
获得的。但这是一个异步调用。
使用此gmStream
不会用于开关下方显示的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)
})
})
})
}
函数操作(方法,参数){
返回新承诺(功能(解决、拒绝){
//配置GridFS(GridFS流)
常数gfs=网格(
MongoInternals.defaultRemoteCollectionDriver().mongo.db,
MongoInternals.NpmModule
)
开关(方法){
案例“旋转”:
gmStream=gm(readStream)
.旋转('#ffffff',参数旋转)
打破
//…还有一些案子。。。
大小写“调整大小”:
gmStream=gm(readStream)
.size(函数(错误、大小){
如果(!err&&size.width>=1000&&size.height>=1000){
gmStream.resize('1000').stream().pipe(writeStream)/您可能希望将承诺链接在一起,以完成您所追求的目标。如果您将交换机案例中的逻辑分解为承诺返回函数,您可能能够实现以下功能(免责声明:我从未使用过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)
})
})
})
})
}