当事件触发时触发 Promise
Trigger Promise when an event fires
我的整个项目都使用 (Bluebird) Promises,但有一个特定的库使用 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();
});
我阅读了 EventEmitter in the middle of a chain of Promises 的答案。
这为我提供了一种执行 '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
});
});
现在如何为 'eventB' 进一步链接?
我假设您想为每个事件做不同的事情链。即使 eventB
是由 connect
的动作触发的,您也可以将其视为另一个逻辑流。
旁注:为了避免让您和任何其他必须阅读此代码库的人感到困惑,我建议您不要使用其他方法来补充承诺,除非您非常[=33] =] 彻底记录它们。
从您的示例来看,以下内容似乎可行。
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()
})
我遇到了同样的问题并编写了一个小型承诺包装库 (controlled-promise),它允许承诺事件发射器。您的示例的解决方案是:
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());
这种方法的好处:
- 现有承诺待处理时自动return
- 轻松访问
resolve()
/ reject()
回调
我的整个项目都使用 (Bluebird) Promises,但有一个特定的库使用 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();
});
我阅读了 EventEmitter in the middle of a chain of Promises 的答案。 这为我提供了一种执行 '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
});
});
现在如何为 'eventB' 进一步链接?
我假设您想为每个事件做不同的事情链。即使 eventB
是由 connect
的动作触发的,您也可以将其视为另一个逻辑流。
旁注:为了避免让您和任何其他必须阅读此代码库的人感到困惑,我建议您不要使用其他方法来补充承诺,除非您非常[=33] =] 彻底记录它们。
从您的示例来看,以下内容似乎可行。
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()
})
我遇到了同样的问题并编写了一个小型承诺包装库 (controlled-promise),它允许承诺事件发射器。您的示例的解决方案是:
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());
这种方法的好处:
- 现有承诺待处理时自动return
- 轻松访问
resolve()
/reject()
回调