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

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

问题描述

所以,我有一个加载页面,并通过jquery.get发出几个请求,填充下拉与他们的值。

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

LoadContact();
};

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



我需要做的是,LoadContact只有在其他方法完成并执行回调后才执行。



但是,我不想在下拉总体回调的结尾放置一些标志,然后我检查,并且必须有一个递归setTimeout调用检查,在调用LoadContact();



在jQuery中有一些东西允许我说:当所有这些都完成后,执行这个。
$ b

更多信息
我正在考虑沿着这些线



  $()。executeAfter(
function(){//当这些操作完成
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
},
LoadContact // Do this
);

...它需要跟踪在执行方法期间发生的ajax调用,并且当它们都完成后,调用LoadContact;



如果我知道如何拦截那个函数中的ajax,我可能写一个jQuery扩展这个。



我的解决方案

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

var stack = [];

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

stack.push(url);
}

var trackAjaxComplete = function事件,XMLHttpRequest,ajaxOptions){
var url = ajaxOptions.url;

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

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

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

var $ this = $(this);

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

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

在调用方法时绑定到ajaxSend事件,并保存一个URL列表>需要更好的唯一ID,但)。然后它解除绑定ajaxSend,因此只跟踪我们关心的请求。它还绑定到ajaxComplete,并从堆栈中删除项目,因为他们返回。当堆栈达到零时,它执行我们的回调,并解除ajaxComplete事件的绑定。

解决方案

http://api.jquery.com/ajaxStop/rel =nofollow noreferrer> .ajaxStop() 如下:

  $(function(){
$(document).ajaxStop(function(){
$(this).unbind ajaxStop); //阻止其他调用完成时再次运行
LoadContact();
});
LoadCategories($('#Category'));
LoadPositions $('#Position'));
LoadDepartments($('#Department'));
});

这将在所有当前请求完成后运行,然后解除绑定本身,所以如果未来ajax调用页面执行。此外,请务必将其放在您的ajax调用之前,以便尽早绑定,更重要的是 .ajaxStart() ,但最佳做法是同时使用。


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

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.

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

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

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

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

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

My Solution

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

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.

解决方案

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

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天全站免登陆