2013-01-18 36 views
8

在此先感謝您看看這個。節點Grunt異步任務循環閉合不工作

我有一個不工作的循環內的異步任務。我做了肯定:

  1. 纏上了我的循環變量的「鑰匙」在封閉,避免了經典的「最後一個值 唯一」的問題,在那裏,循環結束之前異步任務長返回一個值,只有顯示最後一個值。
  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++; 
    } 
} 

參考文獻:

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

回答

12

done()當整個操作完成後,當所有的exec()方法已運行他們的回調,這意味着只應調用。目前,您在每次迭代中都執行done回調。您可以輕鬆地通過節點模塊async如果你想爲了執行exec()方法附帶咕嚕(grunt.util.async(或forEachSeries在使用forEach方法實現這一

像這樣(未測試):

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

tyvm。FAQ使我相信done()必須在任務中爲_each_ asych操作調用,這是一個很大的幫助;我很感謝你的時間:) :) – user1354017

+0

因此,這裏的外賣是該grunt.utils.async實用程序是首選與異步任務工作 - 而不是手動創建閉包等,正確? – user1354017

+0

這是相同的rect,但不僅僅是咕嚕聲。一般來說,在Node.js中工作是非常寶貴的。 https://github.com/caolan/async –