プロジェクト全体で(Bluebird)Promiseを使用していますが、EventEmitterを使用する特定のライブラリが1つあります。
私は次のようなことを達成したいです:
Promise.on('connect', function() {
x.doSomething();
}).then(function() {
return new Promise(function(resolve) {
y.doAction(resolve); // this will result in `eventB` getting emitted
});
}).on('eventB', function() {
z.handleEventB();
}).then(function() {
z.doSomethingElse();
});
私は Promiseのチェーンの真ん中にあるEventEmitter に対する答えを読みました。これにより、「接続」イベントのコールバックを実行する方法が得られます。これが私がこれまでに得た場所です
var p = new Promise(function(resolve) {
emitter.on('connect', resolve);
});
p.on = function() {
emitter.on.apply(emitter, arguments);
return p;
};
p.on('connect', function() {
x.doSomething();
}).then(function() {
return new Promise(function(resolve) {
y.doAction(resolve); // this will result in eventB getting emitted
});
});
次に、「eventB」にさらにチェーンする方法は?
イベントごとに異なる一連の処理を実行したいと思います。 eventB
がconnect
のアクションによってトリガーされたとしても、それを別のロジックストリームのように扱うことができます。
サイドノート:あなたとこのコードベースを読む必要がある他の人の混乱を避けるために、あなたがveryでない限り、追加のメソッドでpromiseを補足しないことをお勧めしますそれらを文書化します。
あなたの例から、次のように機能するようです。
var Promise = require( 'bluebird' )
var emitter = someEmitter()
var connected = new Promise( function( resolve ){
emitter.on( 'connect', resolve )
})
var eventBHappened = new Promise( function( resolve ){
emitter.on( 'eventB', resolve )
})
connected.then( function(){
return x.doSomething()
}).then( function(){
return y.doSomethingElse() // will trigger `eventB` eventually
})
// this promise stream will begin once `eventB` has been triggered
eventBHappened.then( function(){
return z.doSomething()
})
この定数を単純化したい場合
var p = new Promise( function( resolve ){
emitter.on( 'something', resolve )
})
あなたはこのようなものを使うことができます
function waitForEvent( emitter, eventType ){
return new Promise( function( resolve ){
emitter.on( eventType, resolve )
})
}
上記のコードソリューションを
var Promise = require( 'bluebird' )
var emitter = someEmitter()
function waitForEvent( eventEmitter, eventType ){
return new Promise( function( resolve ){
eventEmitter.on( eventType, resolve )
})
}
waitForEvent( emitter, 'connect' ).then( function(){
return x.doSomething()
}).then( function(){
return y.doSomethingElse() // will trigger `eventB` eventually
})
// this promise stream will begin once `eventB` has been triggered
waitForEvent( emitter, 'eventB' ).then( function(){
return z.doSomething()
})
また、JavaScriptの関数はそれらが定義されたスコープをキャプチャするため、このコードをさらに簡略化して
var Promise = require( 'bluebird' )
var emitter = someEmitter()
function waitForEvent( type ){
return new Promise( function( resolve ){
//emitter has been captured from line #2
emitter.on( type, resolve )
})
}
waitForEvent( 'connect' ).then( function(){
return x.doSomething()
}).then( function(){
return y.doSomethingElse() // will trigger `eventB` eventually
})
// this promise stream will begin once `eventB` has been triggered
waitForEvent( 'eventB' ).then( function(){
return z.doSomething()
})
私は同じ問題に直面し、イベントエミッターを約束することを可能にする小さな約束ラッピングライブラリ( 制御された約束 )を書きました。あなたの例の解決策は:
_const Promise = require('bluebird');
const ControlledPromise = require('controlled-promise');
const emitter = someEmitter();
const waiting = new ControlledPromise();
function waitForEvent(type) {
return waiting.call(() => {
emitter.once(type, event => waiting.resolve(event));
});
}
waitForEvent('connect')
.then(() => x.doSomething())
.then(() => waitForEvent('eventB'))
.then(() => z.doSomethingElse());
_
そのようなアプローチの利点:
resolve()
/reject()
コールバックへの簡単なアクセス