純粋なJavascriptを使用する場合(つまり、非同期などのライブラリを使用しない場合):
var fs = require('fs');
var i,
reader = function (i) {
return function (err, data) {
console.log('Inner: ' + i);
}
};
for (i = 0; i < 4; i++) {
console.log('Outer: ' + i);
fs.readFile('/etc/hosts', 'ascii', reader(i));
}
または、あるいは、
var fs = require('fs');
var i;
for (i = 0; i < 4; i++) {
console.log('Outer: ' + i);
fs.readFile('/etc/hosts', 'ascii', function (i, err, data) {
console.log('Inner: ' + i);
}.bind(null, i));
}
var i;
(宣言をループの外に移動してfor
も、この特定の例では実際には何も変更されません。変数の関数スコープのみを持つJavaのようなプログラミング言語とは対照的に、Javascriptに関連するバグを防ぐためのコードスタイルにすぎません。これは、元の例でi
は、forfor
ループだけでなく、モジュール全体に対して宣言されています)。
別のアプローチは、次のようなライブラリを使用することasync
ですunderscore
。
var _ = require('underscore'),
async = require('async'),
fs = require('fs');
async.parallel(_.map(_.range(0, 4), function (i) {
return async.waterfall.bind(null, [
fs.readFile.bind(null, '/etc/hosts', 'ascii'),
function (data, callback) {
console.log("Inner: " + i);
callback();
}
]);
}, function (err) {
if (err) {
console.log("Some read attempt failed");
} else {
console.log("Done reading");
}
});