以前 作ったircbotで、RSS通知を複数のフィードの和集合をとってからつぶやくということをする必要があったので、複数の非同期なRSS取得を待つためにnode-promiseを使ってみたメモ。
Readme.mdを読んだ感じだと、複数処理を待つにはall関数がキモのようなのですが、all関数の使い方がはじめよくわからなくて苦労しました。
実際書いたコードはだいたい以下のようになりました。
feedparser = require 'feedparser' request = require 'request' node_promise = require "node-promise"; feeds = [ "http://some.feed", "http://other.feed" ]; entries = [] promises = feeds.map (url) -> deferred = node_promise.defer() request(url) .pipe(new feedparser []) .on('error', console.log.bind console) .on('data', entries.push.bind entries) .on('end', deferred.resolve.bind deferred) deferred.promise node_promise.when (node_promise.all promises), () -> entries.forEach (entry) -> // Do Something with entry
node-promiseのソースコードをさらっと読んだところ、all関数は配列を引数に取り、その配列中に含まれるpromiseがすべて完了した時点で完了となるpromiseを返すようです。なので、待ちたい複数のpromiseを配列にしてあげてallに食わせ、できたpromiseをwhenで待ってあげればいいことになります。
各feedのentryをすべて同じ配列に詰め込んであげて、feedの読み込み終了にdeferredをresolveするようにしてあげれば一丁上がりです。 あとは all promises を待つwhenですべてのentryが詰め込まれた状態のentriesにアクセスできます。