循环中的节点Grunt异步任务,关闭不起作用

use*_*017 9 closures asynchronous callback node.js gruntjs

提前谢谢你看看这个.

我在一个无效的循环中有一个异步任务.我已经确定:

  1. 将我的循环变量"key"包装在闭包中以避免经典的"仅限最后一个值"问题,其中循环在异步任务返回值之前很久完成,并且仅显示最后一个值.
  2. 调用完成(错误)以完成我的异步任务(根据Gruntjs常见问题解答)
  3. 使用hasOwnProperty()来确保键是对象的实际属性,而不是来自原型.
  4. 遵循node.exec示例的格式,除了将exec的值赋给变量 - 我已经尝试过,但它没有帮助.见下面的第一个参考.

这个功能输出......什么都没有!?由于某种原因,grunt.log.writeln语句甚至没有触发.任务完成且没有错误.我还尝试添加一个20秒的延迟,以防脚本在异步任务返回之前完成.奇怪的是,如果我不调用"完成(错误)",文件将被写入文件(当我用grunt.file.write语句替换writeln时).

var done = this.async(),
    exec = require('child_process').exec,
    myJSON = {
      "file1" : "C:/home/me/jquery.js",
      "file2 " : "C:/home/me/grunt.js",
      ...
      "fileN" : "C:/home/me/N.js"
    },
    count;

for (var key in myJSON) {
    if (myJSON.hasOwnProperty(key)) {
      (function (key) { 
        exec( 'type "' + myJSON[key] + '"', 
          function(error, stdout, stderr) {
            if (error) {
                grunt.log.writeln('!!! exec error: ' + error);
            }
            grunt.log.writeln('stdout: ' + stdout);
            grunt.log.writeln('stderr: ' + stderr);
            done(error);
          }
        );
      })(key);
    count++;
  }
}
Run Code Online (Sandbox Code Playgroud)

参考文献:

http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback https://github.com/gruntjs/grunt/wiki/Frequently-Asked-Questions

Sin*_*hus 13

done()只应在整个操作完成时调用,这意味着所有exec()方法都运行了它们的回调.目前,您正在done每次迭代时执行回调.您可以通过使用grunt附带forEach的节点模块async中的方法轻松实现此目的(grunt.util.async(或者,forEachSeries如果您希望exec()按顺序执行方法).

像这样的东西(未经测试):

var done = this.async();
var exec = require('child_process').exec;
var async = grunt.util.async; // updated
var myJSON = {
  "file1": "C:/home/me/jquery.js",
  "file2": "C:/home/me/grunt.js",
  ...
  "fileN": "C:/home/me/N.js"
};

async.forEach(Object.keys(myJSON), function(el, cb) {
  exec('type "' + myJSON[el] + '"', function(error, stdout, stderr) {
      if (error) {
          grunt.warn('!!! exec error: ' + error)
          return cb(error);
      }
      grunt.log.writeln('stdout: ' + stdout);
      grunt.log.writeln('stderr: ' + stderr);
      cb();
    }
  );
}, function(error) {
  done(!error);
});
Run Code Online (Sandbox Code Playgroud)