9

これをご覧いただきありがとうございます。

機能していないループ内に非同期タスクがあります。私は次のことを確認しました:

  1. ループ変数「キー」をクロージャーでラップして、非同期タスクが値を返すずっと前にループが終了し、最後の値のみが表示されるという、従来の「最後の値のみ」の問題を回避します。
  2. done(error) を呼び出して非同期タスクを完了します (Gruntjs FAQ による)
  3. hasOwnProperty() を使用して、キーがオブジェクトの実際のプロパティであり、プロトタイプからのものではないことを確認します。
  4. exec の値を変数に代入することを除いて、node.exec の例の形式に従ってください。これは私が試しましたが、役に立ちませんでした。以下の最初の参照を参照してください。

この関数は...何も出力しません!? 何らかの理由で、grunt.log.writeln ステートメントが実行されません。タスクはエラーなしで完了します。また、非同期タスクが返される前にスクリプトが終了した場合に備えて、20 秒の遅延を追加してみました。奇妙なことに、「done(error)」を呼び出さないと、ファイルがファイルに書き込まれます (writeln を grunt.file.write ステートメントに置き換えると)。

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++;
  }
}

参考文献:

http://nodejs.org/api/child_process.html#child_process_child_process_exec_command_options_callback https://github.com/gruntjs/grunt/wiki/よくある質問

4

1 に答える 1

13

done()操作全体が完了したとき、つまりすべてのexec()メソッドがコールバックを実行したときにのみ呼び出す必要があります。done現在、各反復でコールバックを実行しています。これは、grunt((、またはメソッドを順番に実行する場合)に付属するforEachノードモジュールasyncのメソッドを使用して簡単に実現できます。grunt.util.asyncforEachSeriesexec()

このようなもの(テストされていません):

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);
});
于 2013-01-20T21:19:22.480 に答える