简体   繁体   English

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

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

The code could be simplified to something like that, 可以将代码简化为类似的内容,

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

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

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

I need to call that callback , after both services getting to ready state. 在两个服务都进入就绪状态后,我需要调用该callback What's the best pattern for that? 最好的方式是什么?

Update: Ideas how to do that with RxJS are welcome :) 更新:欢迎使用RxJS做到这一点:)

You asked for promises, let's see how we can convert one time events to promises, aka promisifying the emitters: 您要求提供诺言,让我们看看如何将一次事件转换为诺言,也就是使发射者多样化

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

Which would let you do: 哪个可以让您做:

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

You can easily aggregate promises which is very nice :) 您可以轻松地汇总承诺,这是非常好的:)

The RxJS way of approaching it would be to use either zip or when/and/thenDo for the synchronization, and fromEvent to manage the EventEmitter 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());

Low-tech 低技术

A low-tech way is to maintain a counter of events and then call the callback when you have received enough: 一种技术含量低的方法是维护事件计数器,然后在收到足够的消息后调用回调:

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

You can look at the event-as-promise package. 您可以查看“ 承诺事件”包。 It convert events into Promise continuously until you are done with all the event processing. 它将持续地将事件转换为Promise,直到完成所有事件处理为止。

In your case, 就你而言

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

Simple and cleaner than RxJS in this case. 在这种情况下,它比RxJS简单,干净。

With jQuery ($) : 使用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> 

Good Luck... 祝好运...

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM