Javascript 触发两个事件时运行代码

Javascript 触发两个事件时运行代码,javascript,events,language-agnostic,Javascript,Events,Language Agnostic,这主要是一个语言不可知的问题 如果我在等待两个事件完成(比如,两个IO事件或http请求),那么处理这个问题的最佳模式是什么。我能想到的一件事是以下(伪js示例) 这是最有效的模式,还是有更优雅的方法来解决这个问题 jQuery 1.5推迟了: 您可以轻松地将它们设置为仅在某些事件被触发时才回拨。在深入讨论细节之前,这里有一些巧妙的方法可以利用我头脑中的lambda功能: function makeCountdownCallback(count, callback) { return f

这主要是一个语言不可知的问题

如果我在等待两个事件完成(比如,两个IO事件或http请求),那么处理这个问题的最佳模式是什么。我能想到的一件事是以下(伪js示例)


这是最有效的模式,还是有更优雅的方法来解决这个问题

jQuery 1.5推迟了:


您可以轻松地将它们设置为仅在某些事件被触发时才回拨。

在深入讨论细节之前,这里有一些巧妙的方法可以利用我头脑中的lambda功能:

function makeCountdownCallback(count, callback) {
    return function() {
        if (--count == 0)
            callback();
    };
}

request1.onComplete = request2.onComplete = makeCountdownCallback(2, function() {
    // do stuff
});
这显然是假设每个事件最多触发一次,并且不利用顺序。

试试#1:下面是一个不需要额外全局变量的解决方案:

request1.onComplete = function() {
    // register new handler for event2 here, overwriting the old one
    request2.onComplete = function() {
        // now they're both done
    }
}

request2.onComplete = function() {
    // register new handler for event1 here, overwriting the old one
    request1.onComplete = function() {
        // now they're both done
    }  
}
首先触发的事件的处理程序将清除另一个事件的旧处理程序,并分配一个新的处理程序,其中包含两个事件完成后需要执行的操作。因为我们在第一个事件的处理程序中重新分配了第二个处理程序(无论是哪个处理程序),所以当第二个处理程序完成时,我们总是知道我们已经完成了

试试#2:如果每种事件类型都不同,下面是一些有用的方法:

function onBoth(fn) {
    var last, done = false;
    return function(e) {
        if (last && last !== e.type && !done) {
            fn(); // done
            done = true;
        }
        last = e.type;
    }
}
例如,在用户滚动并单击之前,这不会提示“完成”:

var both = onBoth(function() {
    alert("done")
});

document.addEventListener("scroll", both, false);
document.addEventListener("click", both, false);
Try#3:可以修改上一次尝试以适用于类似事件:

function onBoth(fn) {
    var last, done = false;
    return function(curr) {
        if (last && last !== curr && !done) {
            fn(); // done
            done = true;
        }
        last = curr;
    }
}
…应该这样使用:

var check = onBoth(function() {
    alert("done")
});

request1.onComplete = function() {
    check(arguments.callee);
}

request2.onComplete = function() {
    check(arguments.callee);
}
基本上,它通过存储对最近执行的回调的引用来检查是否执行了两个不同的回调。它的用法有点笨拙,但它完成了任务(即,如果每个事件执行不止一次,它仍然可以工作)。

一种方法:


库位于。

您是否希望这些事件按特定顺序发生?这会对解决方案产生很大影响。如果您等待任意数量的事件,此解决方案会更好,但如果事件只发生一次,则此解决方案才有效,这有点危险。这有点狡猾。有点疯狂,但很圆滑。这是个不错的解决方案;这一个赢了,尽管我的一部分人确实觉得这是一个有点肮脏的解决方案:)
request1
request2
看起来非常全球化me@Matti-当然是。很明显,我的意思是,它不需要额外的全局标志来指示每个处理程序都已经完成了。它允许您创建一个非常整洁的界面来跟踪多个回调,类似于
afterAllOfThese(def1,def2,def2,function(){…})
。。。当然,除非jQuery已经有了等待多个事件的功能。我希望有一个通用的解决方案,适用于多种语言。
var check = onBoth(function() {
    alert("done")
});

request1.onComplete = function() {
    check(arguments.callee);
}

request2.onComplete = function() {
    check(arguments.callee);
}
Q.spread([
  getA(), getB()
], function(a, b) {
  // Use the results a and b.
// Catch errors:
}).catch(function(error) {
  // Minimal for this example:
  console.log(error);
});