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

时间:2012-03-06 10:41:11

标签: javascript jquery dom jquery-plugins ready

我希望ready事件的处理程序在所有其他处理程序完成后触发。

这对于操纵插件的不良操作非常方便。

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

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


$(function() { alert('my handler'); });​

Fiddle

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

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

5 个答案:

答案 0 :(得分:2)

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

即使readyList是公开的,setTimeout也不会有帮助,因为在您的示例中,readyList的处理程序将在setTimeout之前很久才会被移除readyList 1}}处理程序运行。 .ready()数组也无法控制那种异步代码。

因此,如果您不控制(无法修改)其他代码,那么我真的没有解决方案。但是如果其他代码只是长时间运行,而不是异步,那么就不会出现任何问题,因为如果你的代码是最后一个setTimeout处理程序,那么它应该是#&# 39;其他处理程序执行的时间长短。如果他们的代码是同步,它将迫使您等到他们完成。只是如果他们正在使用异步代码,例如您的{{1}}示例,那么除了检查其他代码之外没有什么可做的,并修改你的,以确保它最后一次。

答案 1 :(得分:0)

您可以使用以下内容:

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

答案 2 :(得分:0)

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

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

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/

答案 3 :(得分:0)

我不知道您是否可以为所有功能(如

)创建队列
var queue = [];
queue .push(fun1);
queue .push(fun2);

//execute the first function and remove it.
(queue .shift())();

答案 4 :(得分:0)

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

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次以保持示例简单,而实际上你当然可以调用不同的函数,但同样的想法适用;在回调函数中你检查计数器。)