触发事件触发事件

我的整个项目使用(蓝鸟)承诺,但有一个使用EventEmitter的特定图书馆。

我想实现这样的事情:

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(); }); 

我在Promises链的中间读到了EventEmitter的答案。 这给了我一个方法来执行“连接”事件的callback。 这是我到目前为止的地方

 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动作触发的,你可以把它看作另一个逻辑stream。

注意:为避免您和其他需要阅读这个代码库的人混淆,我build议不要用其他方法来补充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(){ x.doSomething() }).then( function(){ y.doSomethingElse() // will trigger `eventB` eventually }) // this promise stream will begin once `eventB` has been triggered eventBHappened.then( function(){ 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 ) }) } 

上面的代码解决scheme转化为

 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(){ x.doSomething() }).then( function(){ y.doSomethingElse() // will trigger `eventB` eventually }) // this promise stream will begin once `eventB` has been triggered waitForEvent( emitter, 'eventB' ).then( function(){ 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(){ x.doSomething() }).then( function(){ y.doSomethingElse() // will trigger `eventB` eventually }) // this promise stream will begin once `eventB` has been triggered waitForEvent( 'eventB' ).then( function(){ z.doSomething() }) 

我面临着同样的问题,写了一个小小的承诺包装库( 控制承诺 ),允许事件发射器Promise。 你的例子的解决scheme是:

 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()callback