2014 08 11 01 46 [js] closure inside loops.

今天用Node.js寫了一個轉換簡繁體的小程式,
卻發現當一次處理多個檔案的時候,
會出現全部輸出到同一個檔案去.經過debug之後,
發現Javascript的closure跟我想像中不同.
原本的程式:

var fs = require('fs');
var count = 0;
for (var index =2; index  < process.argv.length; index ++) {
  var val =process.argv[index ];
  console.log("Processing " + val);
  if (index <= 1) {
    continue;
  }
  var file = fs.createReadStream(val, {flags: 'r'});
  var fout = fs.createWriteStream(val+".tc", {flags: 'w'});
  count++;
  file.on('data', function (text) {
     fout.write(toTrad(text.toString())); // <--- fout 這個變數會有問題!!!
  }); 
  file.on('end',function() {
    count--;
    fout.end(function() {
if (count == 0) { process.exit(); } }); }); };

問題出在fout會用到同一個檔案.
在Google過後,發現在Stack Overflow上有人問過同樣問題.
JavaScript closure inside loops – simple practical example - Stack Overflow http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example

簡單來說,就是Javascript的Scope只作用在function上, 在 block 裡是沒用的.
所以, 我只好把東西包進一個function裡,整個就正常了.
程式如下:

var fs = require('fs');
var count = 0;
for (var index =2; index  < process.argv.length; index ++) {
  var val =process.argv[index ];
  console.log("Processing " + val);
  if (index <= 1) {
    continue;
  }
  (function(val) {
    var file = fs.createReadStream(val, {flags: 'r'});
    var fout = fs.createWriteStream(val+".tc", {flags: 'w'});
    count++;
    file.on('data', function (text) {
      fout.write(toTrad(text.toString()));
    });
	  
    file.on('end',function() {
      count--;
      fout.end(function() {
        if (count == 0) {
	  process.exit();
	}
      });
    });
  })(val);
};