事件触发时触发提示

时间:2022-08-17 00:03:04

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()回调