知道所有其他准备好的回调何时完成

我想在完成所有其他处理程序后,我的处理程序就会触发ready事件。
这对于操纵插件的不良操作非常方便。

如果我在所有其他人之后编写我的处理程序,它只能保证它会在所有其他人被解雇触发 ,而不是完成:

 $(function() { setTimeout(function() { alert('other handler'); }, 500); }); $(function() { alert('my handler'); });​ 

小提琴

在该代码中, 我的处理程序首先发出警报

我在jQuery 1.4版之前读到了readyList是公开的。 所以在1.7版本中,我不知道如何判断我的处理程序是否是最后一个处理程序。

如果想法是你不控制其他就绪处理程序,那么给出你的另一个处理程序使用setTimeout例子,如果你的代码将在所有其他代码之后运行,你实际上永远不会知道(不检查其他代码)。

即使它是公共的, readyList也无济于事,因为在你的例子中,具有setTimeout的处理程序将在setTimeout处理程序运行之前很久就从readyList删除。 readyList Array也没有对这种异步代码的任何控制。

所以如果你不控制(不能修改)其他代码,那么我真的没有解决方案。 但是如果其他代码只是长时间运行,而不是异步 ,那么就不会出现任何问题,因为如果你的代码是最后一个分配的.ready()处理程序,那么其他处理程序执行的时间也无关紧要。 如果他们的代码是同步的 ,它将迫使你的代码等到它们完成。 只是如果他们使用异步代码,比如你的setTimeout示例,那么除了检查其他代码并修改你的代码以确保它最后触发之外,没有什么可以做的。

你可以使用这样的东西:

 function Join(cb) { var paths = 0; var triggerCallback = cb; this.add = function () { paths ++; return this.call; }; this.call = function () { paths --; if (paths == 0) if (triggerCallback) triggerCallback(); }; return this; } 

一个例子:

 function finishedAll() { alert("All finished"); } window.join = new Join(finishedAll); function sampleCall(callJoinHandle) { alert("Not done yet."); if (callJoinHandle) callJoinHandle(); } var cb1 = join.add(); setTimeout(function () { sampleCall(cb1); }, 1000); var cb2 = join.add(); setTimeout(function () { sampleCall(cb2); }, 1000); var cb3 = join.add(); setTimeout(function () { sampleCall(cb3); }, 1000); 

一个想法可能是创建一个deferred使用在每个就绪函数(最后一个)之外的数组,在代码片段完成时解析每个函数。

然后,在最后一个ready函数中,您只需使用$.when检查promise解析,然后执行其他一些代码:例如

 var dfdArray = []; $(function() { var dfd = $.Deferred(); dfdArray.push(dfd); setTimeout(function() { console.log('another simple handler'); dfd.resolve(); }, 2000); }); $(function() { var dfd = $.Deferred(); dfdArray.push(dfd); setTimeout(function() { console.log('first handler'); dfd.resolve(); }, 1200); }); $(function() { $.when.apply($, dfdArray).done(function() { alert('my final handler'); }) }); 

请看这里的小提琴: http : //jsfiddle.net/DXaw5/

我不知道你是否有可能为所有函数创建一个队列

 var queue = []; queue .push(fun1); queue .push(fun2); //execute the first function and remove it. (queue .shift())(); 

我通常使用以下模式,只需记住完成异步函数的计数器:

 var fired = 10; var finished = 0; for (var i = 0; i < fired; i++) { // Call an asynchronous function 10 times async_function(function() { // When asynchronous function finishes, // we check if it was the last one. if (++finished == fired) all_ready(); }); } 

coffeescript中也是如此:

 fired = 10 finished = 0 (async_function -> all_ready() if ++finished == ready) for n in [0...fired] 

(我们将相同的函数调用10次以保持示例简单,而实际上您当然可以调用不同的函数,但同样的想法适用;在回调函数中,您检查计数器。)