多个元素上的jQuery插件以异步方式执行

时间:2013-04-25 20:24:24

标签: javascript jquery

编辑 - Js指向脚本文件的链接 - http://jsfiddle.net/r4uH3/

编辑2重新接受回答虽然问题已经结束,但我想加上一些细节,说明我接受以下答案的原因。

另外看到这就是为什么原始代码不起作用 - How do I return the response from an asynchronous call? - 它的重点是AJAX与字面上没有关系,但对异步性的解释对于理解很重要。

FabrícioMatté的答案非常适合我,尽管我稍微适应了它:

(function($){
    // some pre-iteration stuff here

    // iteration vars
    var elementIndex = 0;
    var collectionLength = this.size();
    var ts = this;

    // THIS IS THE KEY BIT AS PER ACCEPTED ANSWER
    // RATHER THAN USING THE NORMAL "this.each"
    (function initLoop(){

        // check if got to last element
        if (elementIndex < collectionLength){

            // DO STUFF, WHATEVER, AS LONG AS YOU DON'T EXPECT
            // ASYNCHRONOUS FUNCTIONS LIKE AJAX / TIMERS NOT TO, WELL, EXECUTE ASYNCHRONOUSLY UNLESS YOU HANDLE THEM PROPERLY!!


            // AND FINALLY - GO TO NEXT ELEMENT IN COLLECTION
            initLoop();
        };

    })());
})(jQuery);

另一个有帮助的事情,虽然不是完全相关,但是使用jQuery(el).data();而不是window.VARIABLENAMEMyNamespace.VARIABLE_NAME使用全局和特定于元素的变量。例如:

// outside of iteration
jQuery(window).data("GLOBAL_STUFF", { /* add properties here and set them later*/ });
var globalData = jQuery(window).data("GLOBAL_STUFF");

// inside iteration
jQuery(currentElement).data("ELEMENT_DATA", { /* add properties here and set them later*/ });
var elementData = jQuery(window).data("ELEMENT_DATA");

// then set props like so (obviously get, similarly..)
globalData.someArrayOfSomething.push(something);
elementData.someBooleanValue = true;

再次感谢Fabrício。


  1. 我编写了一个jQuery插件,与大多数插件一样,可以在多个元素(即一组元素)上执行。

  2. 在函数的this.each(function(i,el){ });部分,我创建了另一个对象类型的新实例(与jQuery无关)并调用其“Init”方法。

  3. 我希望,使用.each循环,它会在完全执行完init方法后循环到下一个实例

  4. 我没有在任何地方使用任何异步(AJAX /计时器)。

  5. 我在“jQuery.fadeIn”或类似内容中使用回调始终

  6. 问题

    Init方法几乎是并行调用的。他们在下一个被调用之前没有完成执行。

    有人可以提出任何已知问题的建议吗?上述“理论”中是否有一些我缺失的东西?

    使用jQuery 2.0。

1 个答案:

答案 0 :(得分:2)

尝试使用以下代码替换for循环:

var i = 0,
    l = window.JRTE_INSTANCES.length;
(function initloop() {
    if (i < l) window.JRTE_INSTANCES[i].Init(initloop);
    i++;
}());

这将通过调用window.JRTE_INSTANCES[0].Init启动init循环。作为回调传递的initloop将在Init结束时再次执行,使用下一个Init开始另一个i,依此类推,直到它遍历所有实例。

这是一个更实用的异步演示,使用与上面非常类似的结构:Fiddle