所有ajax请求完成后执行代码

我有一个非常复杂的搜索,利用多个ajax调用,流程如下:

user performs search on button click ajax request is made to php page which returns json data for each result in returned data additional ajax request is made run function which makes additional ajax call end for each end click function 

这一切都很好,我想做的是在div中显示加载消息并禁用搜索按钮,然后当所有ajax请求完成后重新启用按钮并删除加载消息。

我的脚本在下面,此时按钮的禁用/重新显示几乎瞬间发生,我认为因为ajax调用是asyncronus,我如何重新启用按钮并在所有ajax请求完成后删除加载消息显示数据?

 $('#advKeyBtn').live('click', function() { $('#advKeyBtn').attr('disabled', 'disabled'); $('#searchStatus').html(' Searching Locations...'); $('#results').html(''); //clear existing contents $('#borough_links').html(''); //clear existing contents // handler for advance search button var myUrl = 'getKeyBoroughs.php'; var myKeys = $('#keywords').val(); var myType = $('input[name=keyParams]:checked').val() $.ajax({ url: myUrl, data: "keys=" + myKeys +'&type='+myType, type: "POST", traditional: false, dataType: 'json', error: function(xhr, statusText, errorThrown){ // Work out what the error was and display the appropriate message }, success: function(myData){ // data retrived ok $.each(myData.boroughs, function( intIndex, objValue ){ //alert(myData.boroughs[intIndex].Borough_ID); makeCSS(myData.boroughs[intIndex].Borough_ID); getKeyLocations(myData.boroughs[intIndex].Borough_ID) }) //$('#'+divId).append(myData)//construct location holders } }); $('#advKeyBtn').attr('disabled', ''); $('#searchStatus').html('Search Complete, click on an area to view locations'); }); 

以及从主ajax调用的初始成功调用的函数

 function getKeyLocations(id){ var myUrl = 'getKeyLocations.php'; var myBorough = id; var myKeys = $('#keywords').val(); var myType = $('input[name=keyParams]:checked').val() var divId = '#borough_'+ id; $.ajax({ url: myUrl, type: 'POST', data: 'borough_id='+myBorough+'&keys='+myKeys, error: function(xhr, statusText, errorThrown){ // Work out what the error was and display the appropriate message }, success: function(myData){ $(divId).html(myData); } }); }; 

您必须创建一个能够处理所有请求的函数。 完成所有请求后,启用按钮并显示消息。

 var ajaxLoading = { _requestsInProcess: 0, show: function () { if (this._requestsInProcess == 0) { $('#advKeyBtn').attr('disabled', 'disabled'); $('#searchStatus').html(' Searching Locations...'); } this._requestsInProcess++; }, hide: function () { this._requestsInProcess--; if (this._requestsInProcess == 0) { $('#advKeyBtn').attr('disabled', ''); $('#searchStatus').html('Search Complete, click on an area to view locations'); } } }; 

现在,在所有ajax调用之前使用:

 ajaxLoading.show() 

在你所有的成功方法中使用:

 ajaxLoading.hide() 

希望这可以帮助。

你想要ajaxStartajaxStop ,这里有一些显示加载屏幕的代码。 这么好的小一号class轮。

 $('.loadingElement') .ajaxStart(function() { this.show(); }) .ajaxStop(function() { this.hide(); }); 

对于您的特定用途,它看起来像代码

 $('#advKeyBtn') .ajaxStart(function() { this.attr('disabled', 'disabled'); }) .ajaxStop(function() { this.attr('disabled', ''); }); 

jquery:ajaxStart

每当要发送Ajax请求时,jQuery都会检查是否还有其他未完成的Ajax请求。 如果没有进行,jQuery会触发ajaxStart事件。 已经使用.ajaxStart()方法注册的任何和所有处理程序都会在此时执行。

jquery:ajaxStop

每当Ajax请求完成时,jQuery都会检查是否还有其他未完成的Ajax请求。 如果没有,jQuery会触发ajaxStop事件。 已经使用.ajaxStop()方法注册的任何和所有处理程序都会在此时执行。 如果通过在beforeSend回调函数中返回false来取消最后一个未完成的Ajax请求,则也会触发ajaxStop事件。

来自malsup ,关于ajaxStop和ajaxComplete之间的区别:

当未完成的ajax请求数达到零时,将触发ajaxStop。 收到每个响应后触发ajaxComplete。 ajaxComplete也传递了XHR和设置对象。

是的,AJAX请求是异步的。 一种解决方案是将计数器初始化为已发送的ajax请求的数量,然后在每个响应上减少计数器。 当您达到0时,更新您的状态并重新启用。 请记住,如果网络挂起,您可能希望在超时后自动重新启用。

同意上面的说法,购买我的建议是在超时或失败响应时递减计数器而不是使用计时器。

然后,计数器将计算已完成的响应数(失败与否)。