Javascript:for循环获取数据但顺序被破坏
Javascript: for loop gets data but the order is ruined
我有一个函数,我使用 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");
});
Ajax 根据其定义是异步的,因此您无法确保 return 中的顺序。您可以做的是在输入数据后对数组进行排序你自己。
也许您可以使用 $q.all,结果将按照它们被调用的相同顺序返回,而不管实际 returns 首先是哪个。
由于异步调用,您的请求可能会乱序执行,因此您是正确的。您可以通过使用 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 调用 return 一个承诺,您可以使用 $q.all 等待所有页面加载完毕后再调用您的 cb(pages)
调用,而不是递增 j 并检查(我我假设这就是你的 cb(pages) if 语句试图完成的)
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);
});
我有一个函数,我使用 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");
});
Ajax 根据其定义是异步的,因此您无法确保 return 中的顺序。您可以做的是在输入数据后对数组进行排序你自己。
也许您可以使用 $q.all,结果将按照它们被调用的相同顺序返回,而不管实际 returns 首先是哪个。
由于异步调用,您的请求可能会乱序执行,因此您是正确的。您可以通过使用 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 调用 return 一个承诺,您可以使用 $q.all 等待所有页面加载完毕后再调用您的 cb(pages)
调用,而不是递增 j 并检查(我我假设这就是你的 cb(pages) if 语句试图完成的)
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);
});