nueで関数合成っぽいもの
underscore.jsには関数合成の機能があります。
var _ = require('underscore'); var greet = function(name){ return "hi: " + name; }; var exclaim = function(statement){ return statement + "!"; }; var welcome = _.compose(exclaim, greet); console.log(welcome('moe'));
結果はこう。
hi: moe!
これは、、見ため的にnueのflowに似ている気がする。nueを使うと上のコードはこう書けます。
var flow = require('nue').flow; var greet = function(name){ this.next("hi: " + name); }; var exclaim = function(statement){ this.next(statement + "!"); }; var welcome = flow(exclaim, greet); flow(welcome, console.log)('moe');
結果はもちろんこう。
hi: moe!
結果をreturnしないのでまったく同じではないですが、nueは関数合成っぽい機能を持っているんだと今気づきました。なるほどねー。
例外についての質問に答えました
http://d.hatena.ne.jp/taedium/20111122/p2#c
質問者さんが回答されたことに気づく仕組みってあるんですかねー?
node.jsで使える非同期コントロールフローライブラリ nue 0.3.0リリース
0.3.0をリリースしました。npm install nue でインストールできます。
CHANGELOG
- 新機能 - step関数の中で this.endWith(err) を実行してエラーでflowを終了できるようになりました。flowの最後のstepの this.err に this.endWith(err) で渡したエラーオブジェクトが設定されます。
- 変更 - this.asyc()への引数とthis.async()が返す非同期コールバックの引数(ただし先頭のエラーオブジェクトは除く)は一つにグループ化されるようになりました。
1番目の新機能ですが、エラーを設定してflowを抜け(最後のstepまでジャンプし)たいときに使います。使い方はstepの中で次のようにします。
this.endWith(new Error('エラー'));
2番目の変更点は文章で説明するのがとても難しい。。。以下のコードを見てください。前提として、file1とfile2というファイルがあらかじめ存在し、それぞれ「FILE1」、「FILE2」というデータをもちます。
var flow = require('nue').flow; var fs = require('fs'); var myFlow = flow('myFlow')( function readFiles(file1, file2) { fs.readFile(file1, 'utf8', this.async(file1)); fs.readFile(file2, 'utf8', this.async(file2)); }, function concat(data1, data2) { if (this.err) throw this.err; console.log(data1[0] + ' and ' + data2[0] + ' have been read.'); console.log(data1[1] + data2[1]); this.next(); } ); myFlow('file1', 'file2');
実行結果はこうなります。
file1 and file2 have been read. FILE1FILE2
ポイントはconcate関数のパラメータの数と型です。パラメータの数は直前のstepでthis.async()を呼びだした回数に対応します。そして、型ですが、data1もdata2も長さが2の配列です。最初の要素にはthis.async()への引数(この例ではファイル名)、次の要素にはthis.async()が返すコールバックへの2番目の引数(例だとファイルのデータ)が設定されます。
以前のバージョンで動作させるとconcate関数のパラメータの数は4になりますが(要するに配列にグループ化されない)、this.async()の呼び出し単位にまとめた方がわかりやすいので今回変更しました。
ちなみに、this.async()への引数とthis.async()が返すコールバックへの2番目以降の引数の数が合計で1の場合は、配列ではなくその値が次のstepへの引数に使われます。たとえば次のコードをみてください。上記の例と異なり、this.async()への引数がありません。
var flow = require('nue').flow; var fs = require('fs'); var myFlow = flow('myFlow')( function readFiles(file1, file2) { this.data.files = [file1, file2]; fs.readFile(file1, 'utf8', this.async()); fs.readFile(file2, 'utf8', this.async()); }, function concat(data1, data2) { // data1もdata2も配列ではない console.log(this.data.files.join(' and ') + ' have been read.'); console.log(data1 + data2); this.next(); } ); myFlow('file1', 'file2');
実行結果は最初の例と同じになります。
ところで、「node.jsで使える非同期コントロールフローライブラリ nue そのX」シリーズはまとまりもなく10回までやったのでとりあえず終わりにしたいと思います。終わりにするのはタイトルを固定して「そのX」とつけることでnueの話はこれからも書いていきますけど。たまには思いつくままにブログを書くのも楽しいですね。