My entire project uses (Bluebird) Promises, but there's one particular library that uses EventEmitter.
我的整个项目使用(Bluebird)Promises,但是有一个使用EventEmitter的特定库。
I want to achieve something like:
我希望实现以下目标:
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();
});
I read the answer to EventEmitter in the middle of a chain of Promises. That gives me a way to execute the callback for 'connect' event. Here's where I have got so far
我在Promises链的中间读到了EventEmitter的答案。这为我提供了一种执行'connect'事件回调的方法。这是我到目前为止的地方
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
});
});
Now how to chain further for 'eventB' ?
现在如何为'eventB'进一步链接?
2 个解决方案
#1
16
I assume you want to do a different chain of things for each event. Even if eventB
is triggered by the actions of connect
, you can treat it like another stream of logic.
我假设你想为每个事件做一系列不同的事情。即使eventB由connect的操作触发,您也可以将其视为另一个逻辑流。
Side note: To avoid confusion for you and anyone else who has to read this codebase, I'd recommend against supplementing promises with additional methods unless you are very thorough about documenting them.
附注:为了避免让您和其他任何必须阅读此代码库的人感到困惑,我建议不要使用其他方法补充承诺,除非您非常详细地记录它们。
From your example, it seems like the following would work.
从您的示例来看,似乎以下内容可行。
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()
})
If you'd like to simplify this constant
如果你想简化这个常数
var p = new Promise( function( resolve ){
emitter.on( 'something', resolve )
})
You can use something like this
你可以使用这样的东西
function waitForEvent( emitter, eventType ){
return new Promise( function( resolve ){
emitter.on( eventType, resolve )
})
}
Which turns the code solution above into
这将上面的代码解决方案变成了
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()
})
And because functions in Javascript capture the scope where they were defined, this code could be further simplified to
并且因为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()
})
#2
1
I faced with the same problem and wrote a tiny promise-wrapping library (controlled-promise) that allows to promisify event emitters. The solution for your example is:
我遇到了同样的问题并编写了一个小型的承诺包装库(受控承诺),它允许事件发射器的发布。您的示例的解决方案是:
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());
The benefits of such approach:
这种方法的好处:
- automatic return of existing promise while it is pending
- 现有承诺在待处理时自动返回
- easy access to
resolve()
/reject()
callbacks - 轻松访问resolve()/ reject()回调
#1
16
I assume you want to do a different chain of things for each event. Even if eventB
is triggered by the actions of connect
, you can treat it like another stream of logic.
我假设你想为每个事件做一系列不同的事情。即使eventB由connect的操作触发,您也可以将其视为另一个逻辑流。
Side note: To avoid confusion for you and anyone else who has to read this codebase, I'd recommend against supplementing promises with additional methods unless you are very thorough about documenting them.
附注:为了避免让您和其他任何必须阅读此代码库的人感到困惑,我建议不要使用其他方法补充承诺,除非您非常详细地记录它们。
From your example, it seems like the following would work.
从您的示例来看,似乎以下内容可行。
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()
})
If you'd like to simplify this constant
如果你想简化这个常数
var p = new Promise( function( resolve ){
emitter.on( 'something', resolve )
})
You can use something like this
你可以使用这样的东西
function waitForEvent( emitter, eventType ){
return new Promise( function( resolve ){
emitter.on( eventType, resolve )
})
}
Which turns the code solution above into
这将上面的代码解决方案变成了
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()
})
And because functions in Javascript capture the scope where they were defined, this code could be further simplified to
并且因为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()
})
#2
1
I faced with the same problem and wrote a tiny promise-wrapping library (controlled-promise) that allows to promisify event emitters. The solution for your example is:
我遇到了同样的问题并编写了一个小型的承诺包装库(受控承诺),它允许事件发射器的发布。您的示例的解决方案是:
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());
The benefits of such approach:
这种方法的好处:
- automatic return of existing promise while it is pending
- 现有承诺在待处理时自动返回
- easy access to
resolve()
/reject()
callbacks - 轻松访问resolve()/ reject()回调