我正在尝试允许页面初始加载,同时允许同步ajax post调用运行。
我尝试过使用$ .post,但这不会按照指定的顺序返回我的输出。它返回先加载的内容。有没有办法同时加载同时仍然允许页面加载?
以下是我的两个例子: 示例1 $。发布
var count = 20;
for(var i = 0; i<=count; i++){
$.post("page.php", {variables: variables}, function(data){
$('.container').append(data);
var card = $('.card').last();
card.children('.image').append(i);
});
}
和 示例2 $。ajax
var count = 20;
for(var i = 0; i<=count; i++){
$.ajax({
url: "page.php",
type: "POST",
data: {
page: page,
count: count,
idx: i
},
async: false,
}).done(function(data){
$('.container').append(data);
var card = $('.card').last();
card.children('.image').append(i);
});
}
他们都“工作”,因为他们从正确的地方拉出我需要的一切,并显示正确的信息。在第一个例子中,它随机加载。无论它首先加载的是什么。即使在我append(i)
的帖子中,我也会将数字21
附加到所有内容中。就像它经历了循环(异步)并将最后i
(21)放在每个元素中。
第二个例子完全按照我想要的方式工作,但当然因为它是async:false
,所以在加载每个元素之前它不会加载页面。
如何在不等待页面加载的情况下,充分利用这两个世界并按顺序加载?我在这里缺少什么?
答案 0 :(得分:2)
JavaScript只有功能级别范围。这意味着i
变量在for
循环内的迭代之间共享。当每次迭代的回调执行稍后时,(共享)i
已达到21(正如您所注意到的那样)。
这是JavaScript的常见问题,只能通过在循环中引入新级别的范围来修复。
确保按顺序执行; Kevins的回答是一种推迟执行的简洁方法,直到所有完成。下面的方式应该按照它们到达时的顺序执行它们。
function doPost(j) {
$.post("page.php", {variables: variables}, function(data){
completed[j] = data;
// Check all the responses have been received for the
// previous AJAX requests. If we're missing some, bail.
for (var k=0;k<j;k++) {
if (!completed[k]) {
return;
}
}
// If we reach here, our AJAX request has been holding
// up the show. Execute this, and all successive AJAX
// requests which have been received.
for (var k=j;k<completed.length && completed[k];k++) {
$('.container').append(completed[k]);
var card = $('.card').last();
card.children('.image').append(k);
}
});
}
var count = 20;
var completed = new Array(count);
for(var i = 0; i<=count; i++){
doPost(i);
}
使用Deferreds执行此操作的方法(纯粹是为了有趣和未经测试,但最终更清洁(可以说是)和应该可能有用);
var reqs = [];
var count = 20;
function doPost(i, pendingDeferreds) {
pendingDeferreds.unshift($.post("page.php", {variables: variables}));
return jQuery.when.apply(jQuery, pendingDeferreds).done(function (data) {
data = data[0];
$('.container').append(data);
var card = $('.card').last();
card.children('.image').append(i);
});
};
for(var i = 0; i<=count; i++){
reqs.push(doPost(i, reqs.slice(0, i)));
}
答案 1 :(得分:0)
延期对象。
var count = 20;
var promiseArr = []; // stores promise objects
for(var i = 0; i<=count; i++){
// push promise objects onto promise array
promiseArr.push($.ajax({
url: "scripts/collective/getCards.php",
type: "POST",
data: {
page: page,
count: count,
idx: i
}
}));
}
// when all promise objects in array are resolved, do stuff
$.when.apply($,promiseArr).done(function(){
// arguments for each request are passed as a single argument, here i iterate over them one by one, in order that they were sent, not received.
$.each(arguments,function(i,args){
var data = args[0];
$('.container').append(data);
$('.card').children('.image').text(i);
});
});