Node.js在Callback中获取Exec参数/命令

时间:2014-07-08 16:30:32

标签: javascript node.js asynchronous callback exec

我想在文件系统中操作多个图像(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)。

2 个答案:

答案 0 :(得分:1)

检查async库。特别是async.waterfall方法。我认为这正是你所需要的。

答案 1 :(得分:1)

您可以使用mapasync库中的任何其他并行方法:

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