2012年12月9日日曜日

[node.js, undersore.js]複数の非同期処理の完了を待ち受ける

実行環境
node.js v0.8.3
undersore.js 1.4.3

node.js のプログラムで、複数の非同期処理の終了を待ってから後続の処理を実行する場合、underscore.js の after 関数がとても便利だったので紹介します。

underscore.js のインストール
$ npm install underscore

after 関数

underscore.js の after 関数では、第1引数で渡した数値回、戻り値で返す関数が実行されると、第2引数のコールバックが実行されます、、といってもよくわからないので、
例として、複数のファイルを非同期で削除し、すべてのファイルの削除が完了したらメッセージを表示するプログラムを作成しました。

//カレントディレクトリの、foo, bar, hoge というファイルを非同期で削除する。
//すべてのファイルの削除が完了したら、コンソールにメッセージを表示する。
var fs = require('fs'),
     _ = require('underscore')

var targets = ['foo', 'bar', 'hoge'];

//ファイルの削除を待ち受ける関数
var displayResult  = _.after(targets.length, function(){
  console.log('ファイルの削除が完了しました。');
});

_.each(targets, function(target){
  fs.exists(target, function(exists){
    if(exists){
      fs.unlink(target, function(err){
        if(err) throw err;
        console.log(target + " を削除しました。");
        displayResult(); //ファイルの削除を通知
      });
    } else {
      displayResult(); //ファイルの削除を通知
    }
  });
});

console.log('最初にここが実行されます。');

実行結果

最初にここが実行されます。
hoge を削除しました。
bar を削除しました。
foo を削除しました。
ファイルの削除が完了しました。

想定通りの順番で処理が実行されました!

しかし、上記のサンプルを見てもお分かりの通り、こんなに短いプログラムでも、処理が行ったり来たりしていて、もうスパゲッティ化の兆候が現れはじめてます。。
複数の非同期処理を制御する場合は、かなり慎重にプログラミングする必要がありますね。

でも、after だけでなく、underscore.js には、便利な関数(extend, each, map など)がたくさん用意されているので、積極的に利用していこうと思います。

まとめ


  • 複数の非同期処理の完了を待ち受ける場合は、 underscore.js の after 関数が便利。
  • コードのスパゲッティ化には十分注意する!

0 件のコメント:

コメントを投稿