事件和回调,需要在两个事件触发之前等待并调用回调

时间:2015-08-06 09:58:00

标签: javascript node.js promise rxjs async.js

代码可以简化为类似的东西,

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如何做到这一点:)

5 个答案:

答案 0 :(得分:8)

您要求承诺,让我们看看我们如何将一次性事件转换为承诺,即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
});

您可以轻松汇总非常好的承诺:)

答案 1 :(得分:6)

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

答案 2 :(得分:1)

<强>低技术

一种低技术方式是维持事件的反击,然后在收到足够的信息时调用回调:

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

答案 3 :(得分:0)

您可以查看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更简单,更清洁。

答案 4 :(得分:0)

使用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>

祝你好运...