循环中的 jQuery.ajax()
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17981631/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
jQuery.ajax() inside a loop
提问by MTVS
If I call jQuery.ajax()
inside a loop, would it cause the call in current iteration overwrite the last call or a new XHR object is assigned for the new request?
如果我jQuery.ajax()
在循环内调用,是否会导致当前迭代中的调用覆盖上次调用或为新请求分配新的 XHR 对象?
I have a loop that do this, while from console log I can see requests done 200 ok
but just the result data of the last request in the loop is stored by the request success callback
as supposed .
我有一个循环来执行此操作,而从控制台日志中我可以看到请求已完成,200 ok
但循环中最后一个请求的结果数据仅success callback
按假设由请求存储。
the code:
编码:
var Ajax = {
pages: {},
current_request: null,
prefetch: function () {
currentPath = location.pathname.substr(1);
if(this.pages[currentPath])
{
var current = this.pages[currentPath];
delete this.pages[currentPath];
current['name']=currentPath;
current['title']=$("title").text().replace(' - '.SITE_NAME, '');
current['meta_description']=$("meta[name=description]").attr('content');
current['meta_keywords']=$("meta[name=keywords]").attr('content');
}
var _Ajax = this;
//the loop in question *****
for(var key in this.pages)
{
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+key,
success: function(data) {
_Ajax.pages[key] = data;
}
});
console.debug(this.pages);
}
if(current)
{
this.pages[currentPath] = current;
}
}
};//Ajax Obj
for(var i in pages)
{
Ajax.pages[pages[i]]={};
}
$(function() {
Ajax.prefetch();
});//doc ready
回答by Andy
You'll need a closure for key
:
你需要一个闭包key
:
for(var k in this.pages){
(function(key){
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+key,
success: function(data) {
_Ajax.pages[key] = data;
}
});
console.debug(this.pages);
})(k);
}
that way you make sure that key is always the correct on in each ajax success callback. but other than that it should work
这样您就可以确保在每个 ajax 成功回调中该键始终是正确的。但除此之外它应该可以工作
i made a small closure demonstration using timeout instead of ajax but the principle is the same:
我使用 timeout 而不是 ajax 做了一个小的闭包演示,但原理是一样的:
回答by Yura Zabolotny
You need to use async:falsein you ajax request. It will send the ajax request synchronously waiting for the previous request to finish and then sending the next request.
您需要在 ajax 请求中使用async:false。它将同步发送ajax请求,等待前一个请求完成,然后发送下一个请求。
$.ajax({
type: 'POST',
url: 'http://stackoverflow.com',
data: data,
async: false,
success: function(data) {
//do something
},
error: function(jqXHR) {
//do something
}
});
回答by Jason P
I believe what's happening here has to do with closure. In this loop:
我相信这里发生的事情与关闭有关。在这个循环中:
for(var key in this.pages)
{
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+key,
success: function(data) {
_Ajax.pages[key] = data;
}
});
console.debug(this.pages);
}
The variable key
is actually defined outside the for loop. So by the time you get to the callbacks, the value has probably changed. Try something like this instead:
该变量key
实际上是在 for 循环之外定义的。因此,当您进行回调时,该值可能已更改。试试这样的:
var pages = ["a", "b", "c"];
for (var key in pages) {
console.log('before: ' + key);
(function (thisKey) {
setTimeout(function () {
console.log('after: ' + thisKey);
}, 1000);
})(key);
}
回答by JPRLCol
I was facing the same situation, I solved using the ajax call inside a new function then invoke the function into the loop.
我面临同样的情况,我在新函数中使用 ajax 调用解决了问题,然后将该函数调用到循环中。
It would looks like:
它看起来像:
function a(){
for(var key in this.pages)
{
var paramsOut [] = ...
myAjaxCall(key,paramsOut);
.......
}
}
function myAjaxCall(paramsIn,paramsOut)
{
$.ajax({
method: 'get',
url:'http://'+location.hostname+'/'+paramsIn[0],
success: function(data) {
paramsOut[key] = data;
}
});
}
回答by gezzuzz
This is how I always do a ajax loop..
这就是我总是做一个ajax循环的方式..
I use a recursive function that gets called after the xhr.readyState == 4
我使用一个递归函数,该函数在 xhr.readyState == 4
i = 0
process()
function process() {
if (i < 10) {
url = "http://some.." + i
var xhr = new XMLHttpRequest();
xhr.open("GET", url, true);
xhr.onreadystatechange = function () {
if (xhr.readyState == 4) {
alert(xhr.responseText)
i++
process()
}
}
xhr.send();
} else {
alert("done")
}
}