$.ajax inside $.each 阻塞浏览器
$.ajax inside $.each blocking browser
我有这样的事情:遍历 ID 并针对每个 ID 向服务器(同一域)发出 ajax 请求(async:true
)并将接收到的数据附加到 DOM 元素。这不是一项艰巨的任务,它确实有效。示例代码:
$.each(ids, function (index, id) {
$.ajax({
type: 'POST',
url: "http://localhost/example/"+id,
success: function (data) {
$('#content').append(data);
}
});
});
我的问题是:当我需要循环访问很多 ID(例如 1000 个)时,它会发送很多 ajax,而浏览器 "freeze",当我点击一个 link,它等待所有 ajax 请求完成,然后打开点击的 link。
超时不是一个选项,因为我需要显示尽可能多的接收数据。如果需要 1 秒或 100 秒才能完成,这没有问题,因为用户会看到其他已完成的请求
那么,处理这个问题的最佳方法是什么?当像 this 这样的 link 被点击时停止 ajax 请求?或者有更好的方法
更好的方法是更改请求数据的方式。
如果可能,请尝试将服务器更改为接受多个 ID,并一次使用所有 ID 发出一个请求。这样,您将遍历数据而不是 AJAX 请求。
想一想。对于 1000 个 ID 的数组,每次您点击该功能时,您至少会发出 1001 个请求(页面 1 个!)。如果该请求由数据库支持,则为 1000 个单独的数据库命中。
现代网络浏览器只会处理如此多的并发 AJAX 请求,然后才会将其余请求排队等待稍后处理。您提供的代码可能没有提高性能的好方法。
无需对应用程序进行 1000 ajax 次调用,您可以让服务器 return json 格式
[{ id: 0, content: "A",
id: 1, content: "B",
.
.
id: n, content: "Nth content" }]
像
这样的请求
var idList = [];
$.each(ids, function(index, id) {
idList.push(id);
});
$.ajax({
type: "POST",
data: { id: idList },
success: function(data) {
$.each(data, function(index, v) {
$("#content").append(v.content);
})
}).error(function(response) {
$("#content").append(response);
});
Chrome 据我所知一次可以处理 8 个并发 ajax 请求,像 1000 这样的数字对它来说太多了。上面的代码会将 ajax 调用的次数从 1000 减少到 1。
但是,如果您确实想像这样进行 1000 次调用,那么您最好这样做
var idList = [];
$.each(ids, function(index, id) {
idList.push(id);
});
function makeAjax() {
$.ajax({
type: "POST"
data: { id : idList.pop()},
success: function(data) {
$("#content").append(data);
}
}).done(function() {
if(idList.length>0) {
makeAjax();
}
});
}
下面的代码一次最多产生 8 个 ajax 调用。
var idList = [];
$.each(ids, function(index, id) {
idList.push(id);
});
var MAX_THREADS = 8;
var CURRENT_THREADS = 0;
function makeAjax() {
CURRENT_THREADS++;
$.ajax({
type: "POST"
data: { id : idList.pop()},
success: function(data) {
$("#content").append(data);
}
}).done(function() {
CURRENT_THREADS--;
});
}
function callAjax() {
if(CURRENT_THREADS < MAX_THREADS) {
makeAjax();
}
if(idList.length > 0) {
setTimeout(callAjax, 1000);
}
}
callAjax();
不过我不建议这样做。如果一次获取所有 ID 的内容需要很长时间,您最好使用其他一些解决方案,例如分页。
我有这样的事情:遍历 ID 并针对每个 ID 向服务器(同一域)发出 ajax 请求(async:true
)并将接收到的数据附加到 DOM 元素。这不是一项艰巨的任务,它确实有效。示例代码:
$.each(ids, function (index, id) {
$.ajax({
type: 'POST',
url: "http://localhost/example/"+id,
success: function (data) {
$('#content').append(data);
}
});
});
我的问题是:当我需要循环访问很多 ID(例如 1000 个)时,它会发送很多 ajax,而浏览器 "freeze",当我点击一个 link,它等待所有 ajax 请求完成,然后打开点击的 link。
超时不是一个选项,因为我需要显示尽可能多的接收数据。如果需要 1 秒或 100 秒才能完成,这没有问题,因为用户会看到其他已完成的请求
那么,处理这个问题的最佳方法是什么?当像 this 这样的 link 被点击时停止 ajax 请求?或者有更好的方法
更好的方法是更改请求数据的方式。
如果可能,请尝试将服务器更改为接受多个 ID,并一次使用所有 ID 发出一个请求。这样,您将遍历数据而不是 AJAX 请求。
想一想。对于 1000 个 ID 的数组,每次您点击该功能时,您至少会发出 1001 个请求(页面 1 个!)。如果该请求由数据库支持,则为 1000 个单独的数据库命中。
现代网络浏览器只会处理如此多的并发 AJAX 请求,然后才会将其余请求排队等待稍后处理。您提供的代码可能没有提高性能的好方法。
无需对应用程序进行 1000 ajax 次调用,您可以让服务器 return json 格式
[{ id: 0, content: "A",
id: 1, content: "B",
.
.
id: n, content: "Nth content" }]
像
这样的请求var idList = [];
$.each(ids, function(index, id) {
idList.push(id);
});
$.ajax({
type: "POST",
data: { id: idList },
success: function(data) {
$.each(data, function(index, v) {
$("#content").append(v.content);
})
}).error(function(response) {
$("#content").append(response);
});
Chrome 据我所知一次可以处理 8 个并发 ajax 请求,像 1000 这样的数字对它来说太多了。上面的代码会将 ajax 调用的次数从 1000 减少到 1。
但是,如果您确实想像这样进行 1000 次调用,那么您最好这样做
var idList = [];
$.each(ids, function(index, id) {
idList.push(id);
});
function makeAjax() {
$.ajax({
type: "POST"
data: { id : idList.pop()},
success: function(data) {
$("#content").append(data);
}
}).done(function() {
if(idList.length>0) {
makeAjax();
}
});
}
下面的代码一次最多产生 8 个 ajax 调用。
var idList = [];
$.each(ids, function(index, id) {
idList.push(id);
});
var MAX_THREADS = 8;
var CURRENT_THREADS = 0;
function makeAjax() {
CURRENT_THREADS++;
$.ajax({
type: "POST"
data: { id : idList.pop()},
success: function(data) {
$("#content").append(data);
}
}).done(function() {
CURRENT_THREADS--;
});
}
function callAjax() {
if(CURRENT_THREADS < MAX_THREADS) {
makeAjax();
}
if(idList.length > 0) {
setTimeout(callAjax, 1000);
}
}
callAjax();
不过我不建议这样做。如果一次获取所有 ID 的内容需要很长时间,您最好使用其他一些解决方案,例如分页。