我有一个函数,我使用for循环通过ajax请求获取页面。这一切都很好,除了页面通常是错误的顺序。我想这可能是因为循环内部的异步函数,但我不知道如何解决它。任何建议将不胜感激!
$http.get(link).
success(function (data) {
var num = parseInt($(data).find('.r.m .l').first().text().split(' ').pop());
var total = num + 1;
var pages = [];
var query = removeLastPart(link);
for (var i = page; i < total; i++) {
var full = query + "/" + i + ".html";
$http.get(full).
success(function (data) {
pages.push({image: $(data).find('img#image').attr('src')});
j++;
if (i == total) {
cb(pages);
}
}).
error(function () {
console.log("Error getting chapter");
});
}
}).
error(function () {
console.log("Error getting page number");
});
答案 0 :(得分:3)
由于异步调用您的请求可能无序完成,因此您是正确的。您可以通过使用IIFE或将ajax调用移动到单独的函数并传递应加载页面的索引来解决此问题。
IIFE
for (var i = page; i < total; i++) {
var full = query + "/" + i + ".html";
(function(idx){
$http.get(full).
success(function (data) {
pages[idx] = {image: $(data).find('img#image').attr('src')};
j++;
//assuming j is a counter for knowing when pages are loaded
if (j == total) {
cb(pages);
}
}).
error(function () {
console.log("Error getting chapter");
});
})(i);
}
单独的函数调用
function doAjax(url,pageArray,idx,cb){
$http.get(url).
success(function (data) {
pageArray[idx] = {image: $(data).find('img#image').attr('src')};
j++;
//assuming j is a counter for knowing when pages are loaded
if (j == total) {
cb(pages);
}
}).
error(function () {
console.log("Error getting chapter");
});
}
//....
for (var i = page; i < total; i++) {
var full = query + "/" + i + ".html";
doAjax(full,pages,i,cb);
}
注意,因为$ http调用会返回一个承诺,您可以使用$q.all等待所有页面加载后调用cb(pages)
调用而不是递增j并检查(我假设这是你的if cb(pages)的语句是否正在尝试完成)
function doAjax(url,pageArray,idx){
return $http.get(url).
success(function (data) {
pageArray[idx] = {image: $(data).find('img#image').attr('src')};
}).
error(function () {
console.log("Error getting chapter");
});
}
//....
var ajaxCalls = [];
for (var i = page; i < total; i++) {
var full = query + "/" + i + ".html";
ajaxCalls.push( doAjax(full,pages,i) );
}
$q.all(ajaxCalls).then(function(){
cb(pages);
});
答案 1 :(得分:1)
Ajax的定义是异步的,因此您无法确保订单会返回。您可以做的是在输入数据后,您可以自己对数组进行排序。
答案 2 :(得分:1)
也许你可以使用$ q.all,结果将以他们被调用的相同顺序返回,而不管哪一个实际返回。