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