node.jsで非同期処理を正しく行う
node.jsを改めて学習しています。というか以前やったときは簡単なDB接続やexpressを使ってチャットアプリを作っただけで、表面的な理解だったのでこれではもったいないなと。
今回は非同期処理です。
node.jsといえばイベントループなので、ファイルを読み込む関数を使って挙動を追いたいと思います。
var fs = require('fs'); function f (flag, eventEmitter) { if (flag) { fs.readFile('textfile.txt', 'utf-8', function (err, data) { if (err) { eventEmitter.emit('error', err); } else { eventEmitter.emit('loaded', data); } }); } else { eventEmitter.emit('loaded', null); } }
var events = require('events'); var eventEmitter = new events.EventEmitter(); eventEmitter.on('loaded', function (text) { if (text) { console.log(text); } else { console.log('no data.'); } console.log('data load end.'); }); eventEmitter.on('error', function (err) { console.error(err); process.exit(1); }); f(false, eventEmitter); console.log('data load start.');
これだと、no data.
data load end.
data load start.と表示されて順番がおかしくなります。
これを解決するために、必要に応じてnexttTickという関数を使う必要があります。
else {
process.nextTick(function () {
eventEmitter.emit('loaded', null);
});
}
これによって、f()の第一引数がfalseでも処理の順番が保証され、必ずf()のあとのconsole.log('data load start');が実行されるわけです。