事件和回调,需要等待两个事件触发后调用回调

Events and Callbacks, need to wait before two events triggered and call callback

代码可以简化成这样,

function start(callback) {
    one.on('ready', () => {
        console.log('one server ready');
    });

    two.on('ready', () => {
        console.log('two connection ready');
    });

    one.connect();
    two.start();
}

我需要在两个服务都进入就绪状态后调用它 callback。最好的模式是什么?

更新:欢迎提出如何使用 RxJS 的想法:)

低技术含量

一种低技术含量的方法是维护一个事件计数器,然后在收到足够多的事件后调用回调:

function start (callback) {

    var numSteps = 2;
    var currStep = 0;

    var step = function () {

        currStep++;
        if (currStep === numSteps) {
            callback();
        }
    }

    one.once('ready', () => {

        step();
        console.log('one server ready');
    });

    two.once('ready', () => {

        step();
        console.log('two connection ready');
    });

    one.connect();
    two.start();
}

您要求承诺,让我们看看如何将一次性事件转换为承诺,也就是 promisifying 发射器:

function ready(ee){
    return new Promise(function(resolve) {
        ee.on("ready", resolve); // resolve when ready
    });
}

哪个会让你做:

Promise.all([ready(one), ready(two)]).then(function(){
   // both ready here
});

您可以轻松聚合 promise,这非常好:)

RxJS 的处理方法是使用 zipwhen/and/thenDo 进行同步,并使用 fromEvent 来管理 EventEmitter

function ready(ee) {
  return Rx.Observable.fromEvent(ee, 'ready');
}

//EITHER
var option1 = Rx.Observable.when(ready(one).and(ready(two))
                                 .thenDo((first, second) => "Both Ready!"));

//OR
var option2 = Rx.Observable.zip(ready(one), ready(two), 
                                (first, second) => "Both Ready!");

option1.take(1).subscribe(() => callback());

你可以看看event-as-promise包。它不断地将事件转换为 Promise,直到您完成所有事件处理。

在你的情况下,

import EventAsPromise from 'event-as-promise';

const oneReady = new EventAsPromise();
const twoReady = new EventAsPromise();

one.once('ready', oneReady.eventListener);
two.once('ready', twoReady.eventListener);

await Promise.all([one.upcoming(), two.upcoming()]);

在这种情况下比 RxJS 更简单、更清晰。

jQuery ($):

$('#greet').one('click', function(evt){
  $(evt.currentTarget).one('click', function(){
    alert('Hi!');
  });
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<button id="greet">Greet ONLY on second click.</button>

祝你好运...