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

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

问题描述

所以,我有一个加载页面,并通过 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.

但是,我不想在下拉人口回调的末尾放置一堆标志,然后我检查这些标志,并且必须在调用 LoadContact() 之前进行递归 setTimeout 调用检查;

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."?

更多信息我在想这些事情

$().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;

如果我知道如何拦截在该函数中生成的 ajax,我可能会编写一个 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天全站免登陆