等待多个异步调用完成后再继续 [英] Waiting on multiple asynchronous calls to complete before continuing

查看:144
本文介绍了等待多个异步调用完成后再继续的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

所以,我有一个页面加载和通过jquery.get提出了一些要求来填充下拉菜单与他们的价值观。

So, I have a page that loads and through jquery.get makes several requests to populate drop downs with their values.

$(function() {
    LoadCategories($('#Category'));
    LoadPositions($('#Position'));
    LoadDepartments($('#Department'));

    LoadContact();
};

然后调用LoadContact();这确实另一个呼叫,当它返回它填充窗体上的所有字段。的问题是,常常,该下拉菜单是不是所有的填充,因此,它不能将它们设置为正确的值。

It then calls LoadContact(); Which does another call, and when it returns it populates all the fields on the form. The problem is that often, the dropdowns aren't all populated, and thus, it can't set them to the correct value.

我需要什么,能够做的,就是莫名其妙地LoadContact只有当其他方法完成,完成回调执行执行。

What I need to be able to do, is somehow have LoadContact only execute once the other methods are complete and callbacks done executing.

不过,我不希望有放一堆标志中的下拉人口回调结束后,我再检查,并且必须有一个递归方法setTimeout检查,要求LoadContact前();

But, I don't want to have to put a bunch of flags in the end of the drop down population callbacks, that I then check, and have to have a recursive setTimeout call checking, prior to calling LoadContact();

有什么jQuery中,让我说,执行这一点,当所有这些都完成。

Is there something in jQuery that allows me to say, "Execute this, when all of these are done."?

更多资讯
我沿着这些路线思考的东西。

More Info I am thinking something along these lines

$().executeAfter(
    function () {   // When these are done
        LoadCategories($('#Category'));
        LoadPositions($('#Position'));
        LoadDepartments($('#Department'));
    },
    LoadContact // Do this
);

...这将需要保持的方法的执行过程中所发生的Ajax调用的跟踪,当他们都完成后,调用LoadContact;

...it would need to keep track of the ajax calls that happen during the execution of the methods, and when they are all complete, call LoadContact;

如果我知道如何拦截在该功能正在取得阿贾克斯,我大概可以写一个jQuery扩展做到这一点。

If I knew how to intercept ajax that are being made in that function, I could probably write a jQuery extension to do this.

我的解决方案

;(function($) {
    $.fn.executeAfter = function(methods, callback) {

        var stack = [];

        var trackAjaxSend = function(event, XMLHttpRequest, ajaxOptions) {
            var url = ajaxOptions.url;

            stack.push(url);
        }

        var trackAjaxComplete = function(event, XMLHttpRequest, ajaxOptions) {
            var url = ajaxOptions.url;

            var index = jQuery.inArray(url, stack);

            if (index >= 0) {
                stack.splice(index, 1);
            }

            if (stack.length == 0) {
                callback();
                $this.unbind("ajaxComplete");
            }
        }

        var $this = $(this);

        $this.ajaxSend(trackAjaxSend)
        $this.ajaxComplete(trackAjaxComplete)

        methods();
        $this.unbind("ajaxSend");
    };
})(jQuery);

这绑定到ajaxSend事件而被调用,并保持URL列表的方​​法(需要一个更好的唯一的ID,虽然)被调用。然后,它从ajaxSend所以只有我们关心的跟踪请求解除绑定。它还结合ajaxComplete当他们返回从堆栈中删除的项目。当堆栈达到零,执行我们的回调,并解除绑定ajaxComplete事件。

This binds to the ajaxSend event while the methods are being called and keeps a list of urls (need a better unique id though) that are called. It then unbinds from ajaxSend so only the requests we care about are tracked. It also binds to ajaxComplete and removes items from the stack as they return. When the stack reaches zero, it executes our callback, and unbinds the ajaxComplete event.

推荐答案

您可以使用 .ajaxStop() 是这样的:

You can use .ajaxStop() like this:

$(function() {
  $(document).ajaxStop(function() {
    $(this).unbind("ajaxStop"); //prevent running again when other calls finish
    LoadContact();
  });
  LoadCategories($('#Category'));
  LoadPositions($('#Position'));
  LoadDepartments($('#Department'));
});

在当前所有的请求都完成再解除绑定本身,所以如果在页面未来Ajax调用执行它不跑这跑。此外,请务必把它在你的Ajax调用,所以它必然会得到足够早,它与 .ajaxStart更重要() ,但最佳实践是既做到这一点。

This will run when all current requests are finished then unbind itself so it doesn't run if future ajax calls in the page execute. Also, make sure to put it before your ajax calls, so it gets bound early enough, it's more important with .ajaxStart(), but best practice to do it with both.

这篇关于等待多个异步调用完成后再继续的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆