我想在文件系统中操作多个图像(imagemagick'转换命令)。图像数量将是动态的,但是对于此示例,请使用8.这些图像中没有一个相互依赖,因此我不想调用8个同步exec
s(execSync
) 。
当前代码:
var exec = require('child_process').exec,
outfile = 'finename123',
jsonreturn = [],
done = function(){
//all images done move on.
},
i = 1;
for(; i <= 8; i++){
var angle = (i - 1) * 45,
bg = __dirname + '/../contentRam/pov/mug11-' + angle + '.png',
child = exec('convert ' + bg + ' ' + outfile + i + '.png -compose darken -resize 400x400 -composite png:-', {
encoding: 'binary',
maxBuffer: 5000 * 1024
}, function(error, stdout, stderr){
jsonreturn.push({
src: 'data:image/png;base64,' + new Buffer(stdout, 'binary').toString('base64'),
angle: angle
});
console.log(angle);
if(jsonreturn.length === 8){
done();
}
});
}
正如您所看到的,我的基本问题是angle
将始终是最后一个(在本例中为315),因为它在任何回调运行之前完成了for
。有没有办法让我传递一个值以及数据exec
返回到回调中所以我知道哪个文件刚刚完成而没有使它同步?我已经考虑过能够获得在回调中使用exec
调用的参数或整个命令,但我没有运气。我还调查了imagemagick的convert
命令的额外参数,以传递额外的数据,也没有运气。
我唯一能想到的是让for循环不运行exec
而是写入字符串。因此,从child =
到exec
的末尾的所有内容都是字符串。完成后,每个字符串 exec
都会在回调中使用正确的参数和正确的数据,因为此时它并不依赖于回调之外的i
来查看它所在的exec
,回调就是按照它需要执行的方式写出来的。这意味着(在这种情况下)将有8个不同的exec
函数具有回调,并且所有函数都在eval
的字符串中。我不能手动执行此操作,因为有动态数量的图像(有时为8,其他时间为3)。
答案 0 :(得分:1)
检查async库。特别是async.waterfall方法。我认为这正是你所需要的。
答案 1 :(得分:1)
您可以使用map
或async库中的任何其他并行方法:
var async = require('async')
, exec = require('child_process').exec
, files = ['file1.txt', 'file2.txt']
async.map(files
, function (file, callback) {
// you get the context of each file
exec('exec some command with your file', {} , function(error, stdout, stderr){
// you can use the same file reference
callback(null, {
src: '' // your buffer
, angle: files.indexOf(file) * 20 // calculate angle based on the current file
})
})
}
, function (err, results) {
// results have all {src,angle} items
})