Caf*_*eek 55 javascript jquery asynchronous callback
所以,我有一个加载的页面,并通过jquery.get发出几个请求,用它们的值填充下拉列表.
$(function() {
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
LoadContact();
};
Run Code Online (Sandbox Code Playgroud)
然后调用LoadContact(); 这是另一个调用,当它返回时,它会填充表单上的所有字段.问题是通常,下拉列表并非全部填充,因此,它无法将它们设置为正确的值.
我需要做的是,只要其他方法完成并且回调完成执行,LoadContact就会以某种方式执行.
但是,我不想在下拉填充回调的末尾放置一堆标志,然后检查,并且在调用LoadContact()之前必须进行递归的setTimeout调用检查;
jQuery中有什么东西可以让我说,"当所有这些都完成时执行它."?
更多信息 我正在考虑这些问题
$().executeAfter(
function () { // When these are done
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
},
LoadContact // Do this
);
Run Code Online (Sandbox Code Playgroud)
...它需要跟踪在执行方法期间发生的ajax调用,并且当它们全部完成时,调用LoadContact;
如果我知道如何拦截在该函数中创建的ajax,我可能会编写一个jQuery扩展来执行此操作.
我的解决方案
;(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);
Run Code Online (Sandbox Code Playgroud)
这会在调用方法时绑定到ajaxSend事件,并保留一个调用的url列表(需要更好的唯一id).然后它从ajaxSend解除绑定,因此只跟踪我们关心的请求.它还绑定到ajaxComplete并在返回时从堆栈中删除项目.当堆栈达到零时,它将执行我们的回调,并取消绑定ajaxComplete事件.
Nic*_*ver 43
你可以.ajaxStop()像这样使用:
$(function() {
$(document).ajaxStop(function() {
$(this).unbind("ajaxStop"); //prevent running again when other calls finish
LoadContact();
});
LoadCategories($('#Category'));
LoadPositions($('#Position'));
LoadDepartments($('#Department'));
});
Run Code Online (Sandbox Code Playgroud)
这将在所有当前请求完成后运行,然后取消绑定,以便在页面执行中未来的ajax调用时它不会运行.另外,一定要把它放在你的ajax调用之前,这样它就能早点受到限制,但更重要的是.ajaxStart(),但是最好的做法是同时使用它们.
KPD*_*KPD 17
扩展Tom Lianza的答案,$.when()现在是比使用更好的方法.ajaxStop().
唯一需要注意的是,您需要确保在返回a时需要等待的异步方法Deferred object.幸运的是,jQuery ajax调用默认情况下已经这样做了.因此,要从问题中实现场景,需要等待的方法看起来像这样:
function LoadCategories(argument){
var deferred = $.ajax({
// ajax setup
}).then(function(response){
// optional callback to handle this response
});
return deferred;
}
Run Code Online (Sandbox Code Playgroud)
然后在所有三个ajax调用返回后调用LoadContact()并可选地执行它们自己的单独回调:
// setting variables to emphasize that the functions must return deferred objects
var deferred1 = LoadCategories($('#Category'));
var deferred2 = LoadPositions($('#Position'));
var deferred3 = LoadDepartments($('#Department'));
$.when(deferred1, deferred2, deferred3).then(LoadContact);
Run Code Online (Sandbox Code Playgroud)
如果您使用的是Jquery 1.5或更高版本,我怀疑Deferred对象是您最好的选择:http: //api.jquery.com/category/deferred-object/
帮助方法,当时,也很不错:http: //api.jquery.com/jQuery.when/
| 归档时间: |
|
| 查看次数: |
40031 次 |
| 最近记录: |