【追記1】例外処理を含めた簡単なサンプルも書いてみました。(2015.04.22)
https://gist.github.com/ishiduca/956ee21635bfc40537e7
【追記2】ActionCeatorsでは、ユーザーに直接.writeメソッドに触れさせないようにしました。
簡単なチャットアプリで試してみました。https://github.com/ishiduca/streamed-flux-demo
モチベーション
データの流れを一方向に保つというのがFluxの肝だろうから、各要素の実装をStreamにしてパイプでつなげればいいんじゃないのか。という発想
構成要素
ActionCreators (Action)
Readableなストリームならなんでも
var es = require('event-stream')
var assign = require('object-assign')
// ユーザには直接writeメソッドを使わせたくないので
// メソッドを生やしてみる
var actionStream = module.exports = assign(
es.map(function (payload, cb) {
cb(null, payload)
})
, {
sendMsg: function (value) {
this.write({
actionType: 'user.sendMessage'
, value: value
})
}
}
)
Dispatcher
Actionから流れてきたデータをStoreに流すだけのストリーム。シングルトン。
var dispatcherStream = module.exports = es.map(function (data, cb) {
cb(null, data)
})
Store
Dispatcherから流れてきたデータを選別して(、処理が必要な場合は処理して)下流に流すストリーム
var storeStream = module.exports = es.map(function (data) {
if ('user.sendMessage' === data.actionType) {
// 加工が必要な場合はこの辺で加工する
cb(null, data.value)
} else {
cb() // 下流に流さない場合
}
})
View
React.jsとか。
ActionCreatorsをDispatcherにつなぐ
Actionがひとつの場合は
actionStream.pipe(dispatcherStream)
複数ある場合は
es.merge(
actionStream1
, actionStream2
, ...
)
.pipe(dispatcherStream)
DispatcherをStoreにつなぐ
dispatcherStream.pipe(storeStream)
StoreからViewへ
storeStream.on('data', function (message) {
this.setState({message: message})
}.bind(this))
ViewからActionへ
handleClick: function (ev) {
actionStream.sendMsg(this.refs.inputMsg.getDOMNode().value)
}
雑感
記述量が多い?
FacebookのFluxチュートリアル(記述量が多いけど、何をやってるのかわかりやすくてよい)を見習って、こちらも途中を端折らず描いてます。
心配事
パイプしまくる規模になったら、登録できるイベントの上限にすぐ到達してしまいそう。
event-streamが便利
ストリームの実装で楽をするのに event-stream
を使います。
https://www.npmjs.com/package/event-stream