【问题标题】:Node.js get Exec parameters/command in CallbackNode.js 在回调中获取执行参数/命令
【发布时间】:2014-08-29 11:55:53
【问题描述】:

我的文件系统中有多个我想操作的图像(imagemagick 的转换命令)。图像的数量将是动态的,但在此示例中,我们使用 8 个。这些图像都不是相互依赖的,所以我不想调用 8 个同步 execs (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 函数,并且所有函数都在一个字符串中,即 evaled。我无法手动执行此操作,因为图像的数量是动态的(有时是 8 个,有时是 3 个)。

【问题讨论】:

    标签: javascript node.js asynchronous callback exec


    【解决方案1】:

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

    【讨论】:

    • 感谢您的回复。如果我错了,请纠正我,但 async.waterfall 基本上允许将数据从 1 个异步函数传递到下一个函数,依此类推。这基本上使每个异步函数不会同时运行,而是按顺序运行(这与我想要做的相反)。我的问题不在于将数据从一个异步函数传递到另一个。我的问题是,在每个回调本身中,我不知道该回调属于哪个exec 命令,所以我不知道完成了哪个文件(因为即使它们按顺序开始,它们可以 i> 无序完成)。
    • async.waterfall 是对的。那么,您可以尝试使用async.parallel 来满足您的要求。希望对您有所帮助。
    【解决方案2】:

    您可以使用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 
      })
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-03-21
      • 2020-09-15
      • 1970-01-01
      • 2012-10-08
      • 2018-05-08
      • 2016-10-10
      • 2011-11-03
      • 2015-08-28
      相关资源
      最近更新 更多