react-router@1.0.0-rc3
を使っていると、onEnterでStoreを更新して、終わってからRouteへ移動したい。Angularで言うui-routerのresolveが欲しいと思っていました。
EventEmitter
を継承して.emit
をオーバーライドすれば対応可能です。軽くテストを通したライブラリも公開しています。1
具体的には下記のように実装します。
async-emitter.js
// Dependencies
import {EventEmitter} from 'events'
// Public
class AsyncEmitter extends EventEmitter{
emit(event,...args){
let promises= []
this.listeners(event).forEach(listener=>{
promises.push(listener(...args))
})
return Promise.all(promises)
}
}
export default AsyncEmitter
最後にPromise.allで結果を梱包するので、配列の結果か、最初のエラーを補足します。
async-emitter-test.js
import AsyncEmitter from './async-emitter'
let emitter= new AsyncEmitter
// Add event listeners
emitter.on('foo',(arg1)=>{
return new Promise((resolve,reject)=>{
if(arg1==null){
resolve('bar')
}
else{
reject(new Error('beep'))
}
})
})
// Dispatch the `foo` event
emitter.emit('foo')
.then(values=>{
console.log(values[0] === 'bar') // true
// expect to be rejected
return emitter.emit('foo','kaboom')
})
.catch(reason=>{
console.error(reason.message === 'beep') // true
})
babel-node async-emitter-test.js
true
true
react-router@1.0.0-rc3
では、onEnterの第三引数にcallbackを受けますので、上手く活用出来ると思います。
-
v0.4.0
から、.emit
は.emitParallel
にメソッド名を変更しました。 ↩