jam*_*lin 644 javascript ajax jquery
如何使函数等到所有jQuery Ajax请求在另一个函数内完成?
简而言之,我需要等待所有Ajax请求在执行下一个之前完成.但是怎么样?
Ale*_*lex 875
jQuery现在为此目的定义了一个when函数.
它接受任意数量的Deferred对象作为参数,并在所有这些对象解析时执行一个函数.
这意味着,如果要启动(例如)四个Ajax请求,然后执行一个动作他们完成的时候,你可以这样做:
$.when(ajax1(), ajax2(), ajax3(), ajax4()).done(function(a1, a2, a3, a4){
// the code here will be executed when all four ajax requests resolve.
// a1, a2, a3 and a4 are lists of length 3 containing the response text,
// status, and jqXHR object for each of the four ajax calls respectively.
});
function ajax1() {
// NOTE: This function must return the value
// from calling the $.ajax() method.
return $.ajax({
url: "someUrl",
dataType: "json",
data: yourJsonData,
...
});
}
Run Code Online (Sandbox Code Playgroud)
在我看来,它使得语法清晰明确,并避免涉及任何全局变量,如ajaxStart和ajaxStop,这些变量可能会在页面开发时产生不必要的副作用.
如果你事先不知道需要等待多少个ajax参数(即你想使用可变数量的参数),它仍然可以完成,但只是有点棘手.请参阅将Deferreds数组传递给$ .when()(也许是jQuery.当使用可变数量的参数进行故障排除时).
如果你需要更深入地控制ajax脚本等的失败模式,你可以保存返回的对象.when()- 它是一个包含所有原始ajax查询的jQuery Promise对象.您可以在其上调用.then()或.fail()添加详细的成功/失败处理程序.
Ars*_*yan 282
如果您想等到文档中的所有ajax请求都完成,无论它们有多少,只需以$.ajaxStop这种方式使用事件:
$(document).ajaxStop(function () {
// 0 === $.active
});
Run Code Online (Sandbox Code Playgroud)
在这种情况下,无需猜测将来可能完成的应用程序中有多少请求.在某些情况下,ajax请求可以是函数内部逻辑的一部分,这可能非常复杂(例如调用其他函数),在这种情况下,您可能不会等到所述函数完成其整个逻辑而不是仅等待ajax部分完成.
$.ajaxStop这里也可以绑定到HTML您认为可能被修改的任何节点ajax.
同样,此处理程序的目的是知道何时没有活动 ajax不清除或重置某些内容.
PS如果您不介意使用ES6语法,则可以使用Promise.all已知ajax方法.例:
Promise.all([ajax1(), ajax2()]).then(() => {
// all requests finished successfully
}).catch(() => {
// all requests finished but one or more failed
})
Run Code Online (Sandbox Code Playgroud)
这里有一个有趣的一点是,它的作品都与Promises和$.ajax请求.这是jsFiddle演示的最后一个.
jam*_*lin 31
我发现了一个很好的答案被gnarf我的自我,这正是我一直在寻找:)
jQuery ajaxQueue
//This handles the queues
(function($) {
var ajaxQueue = $({});
$.ajaxQueue = function(ajaxOpts) {
var oldComplete = ajaxOpts.complete;
ajaxQueue.queue(function(next) {
ajaxOpts.complete = function() {
if (oldComplete) oldComplete.apply(this, arguments);
next();
};
$.ajax(ajaxOpts);
});
};
})(jQuery);
Run Code Online (Sandbox Code Playgroud)
然后你可以像这样在队列中添加一个ajax请求:
$.ajaxQueue({
url: 'page.php',
data: {id: 1},
type: 'POST',
success: function(data) {
$('#status').html(data);
}
});
Run Code Online (Sandbox Code Playgroud)
BBo*_*eld 20
注意:上述答案使用的是撰写本答案时不存在的功能.我建议使用jQuery.when()而不是使用这些方法,但我将离开答案用于历史目的.
-
您可以使用简单的计数信号量,但是如何实现它将取决于您的代码.一个简单的例子就是......
var semaphore = 0, // counting semaphore for ajax requests
all_queued = false; // bool indicator to account for instances where the first request might finish before the second even starts
semaphore++;
$.get('ajax/test1.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test2.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test3.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
semaphore++;
$.get('ajax/test4.html', function(data) {
semaphore--;
if (all_queued && semaphore === 0) {
// process your custom stuff here
}
});
// now that all ajax requests are queued up, switch the bool to indicate it
all_queued = true;
Run Code Online (Sandbox Code Playgroud)
如果您希望它像{async:false}那样运行,但您不想锁定浏览器,则可以使用jQuery队列完成相同的操作.
var $queue = $("<div/>");
$queue.queue(function(){
$.get('ajax/test1.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test2.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test3.html', function(data) {
$queue.dequeue();
});
}).queue(function(){
$.get('ajax/test4.html', function(data) {
$queue.dequeue();
});
});
Run Code Online (Sandbox Code Playgroud)
ola*_*ure 20
使用该ajaxStop活动.
例如,假设您在获取100个ajax请求时有一个loading ...消息,并且您希望在加载后隐藏该消息.
来自jQuery doc:
$("#loading").ajaxStop(function() {
$(this).hide();
});
Run Code Online (Sandbox Code Playgroud)
请注意,它将等待在该页面上完成的所有ajax请求.
jQuery 允许您指定是否希望 ajax 请求是异步的。您可以简单地使 ajax 请求同步,然后其余代码在它们返回之前不会执行。
例如:
jQuery.ajax({
async: false,
//code
});
Run Code Online (Sandbox Code Playgroud)
javascript是基于事件的,所以你永远不应该等待,而是设置钩子/回调
您可以使用jquery.ajax的success/complete方法
或者你可以使用.ajaxComplete:
$('.log').ajaxComplete(function(e, xhr, settings) {
if (settings.url == 'ajax/test.html') {
$(this).text('Triggered ajaxComplete handler.');
//and you can do whatever other processing here, including calling another function...
}
});
Run Code Online (Sandbox Code Playgroud)
虽然你应该发布一个关于你的ajax请求如何被称为更准确的伪代码...
一个小的解决方法是这样的:
// Define how many Ajax calls must be done
var ajaxCalls = 3;
var counter = 0;
var ajaxCallComplete = function() {
counter++;
if( counter >= ajaxCalls ) {
// When all ajax calls has been done
// Do something like hide waiting images, or any else function call
$('*').css('cursor', 'auto');
}
};
var loadPersons = function() {
// Show waiting image, or something else
$('*').css('cursor', 'wait');
var url = global.ctx + '/loadPersons';
$.getJSON(url, function(data) {
// Fun things
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCountries = function() {
// Do things
var url = global.ctx + '/loadCountries';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
var loadCities = function() {
// Do things
var url = global.ctx + '/loadCities';
$.getJSON(url, function(data) {
// Travels
})
.complete(function() { **ajaxCallComplete();** });
};
$(document).ready(function(){
loadPersons();
loadCountries();
loadCities();
});
Run Code Online (Sandbox Code Playgroud)
希望可能有用......
| 归档时间: |
|
| 查看次数: |
513748 次 |
| 最近记录: |