循环中的jQuery.ajax()

MTV*_*TVS 9 ajax jquery xmlhttprequest

如果我jQuery.ajax()在循环内部调用,是否会导致当前迭代中的调用覆盖最后一次调用,或者为新请求分配了新的XHR对象?

我有一个循环来执行此操作,而从控制台日志我可以看到请求已完成,200 ok但只是循环中最后一个请求的结果数据由请求存储success callback为假设.

代码:

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
Run Code Online (Sandbox Code Playgroud)

And*_*ndy 27

你需要一个关闭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);
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以确保每个ajax成功回调中的键始终是正确的.但除此之外,它应该工作

我使用超时而不是ajax做了一个小闭包演示,但原理是一样的:

http://jsfiddle.net/KS6q5/


小智 9

您需要在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
    }
});
Run Code Online (Sandbox Code Playgroud)


Jas*_*n P 6

我相信这里发生的事情与关闭有关.在这个循环中:

    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);
    }
Run Code Online (Sandbox Code Playgroud)

该变量key实际上是在for循环之外定义的.因此,当您进入回调时,该值可能已更改.尝试这样的事情:

http://jsfiddle.net/VHWvs/

var pages = ["a", "b", "c"];

for (var key in pages) {
    console.log('before: ' + key);
    (function (thisKey) {
        setTimeout(function () {
            console.log('after: ' + thisKey);
        }, 1000);
    })(key);
}
Run Code Online (Sandbox Code Playgroud)


gez*_*uzz 3

这就是我总是做 ajax 循环的方式..

我使用一个递归函数,该函数在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")
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 是的..这是故意设置为一次运行1..避免了一次打开100个请求的瓶颈..真的取决于他想要做什么..如果他只打开几个请求然后一次完成它们是很好..另外,如果您不关心请求返回的顺序..因为第三个请求可能会在第一个请求之前完成.. (2认同)