我希望我的ready
事件处理程序在所有其他处理程序都完成后启动
它非常方便地处理插件不需要的操作。
如果我在所有其他人之后编写我的处理程序,它只保证它会在所有其他被解雇之后被解雇,而不是完成:
$(function() {
setTimeout(function() { alert('other handler'); }, 500);
});
$(function() { alert('my handler'); });
Fiddle
在该代码中,我的处理程序首先发出警报。
我读到在jQuery版本1.4
之前,readyList
是公开的。所以在版本1.7
中,我不知道如何判断我的处理程序是否是最后一个处理程序。
如果你的想法是不控制其他准备好的处理程序,那么在你的例子中,另一个处理程序使用了setTimeout
,你永远无法真正知道(如果不检查其他代码)你的代码是否会在所有其他代码之后运行。
readyList
即使是公共的也没有帮助,因为在您的示例中,早在setTimeout
处理程序运行之前,带有setTimeout
的处理程序就会从readyList
中删除。readyList
阵列也不能控制这种异步代码。
所以,如果你不能控制(不能修改)其他代码,那么我真的没有解决方案。但是,如果其他代码只是长时间运行,而不是异步,那么就不会有任何问题,因为如果您的代码是最后分配的.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
数组,用于每个就绪函数(除了最后一个),并在代码段完成时解析每个函数。
然后,在最后一个就绪函数中,您可以简单地用$.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();
});
}
咖啡脚本中也是如此:
fired = 10
finished = 0
(async_function -> all_ready() if ++finished == ready) for n in [0...fired]
(为了简化示例,我们调用同一个函数10次,而实际上您当然可以调用不同的函数,但同样的想法适用;在回调函数中,您可以检查计数器。)