Jquery 等待ajax成功结束,然后再进行下一次迭代

Jquery 等待ajax成功结束,然后再进行下一次迭代,jquery,ajax,asynchronous,Jquery,Ajax,Asynchronous,我有一个for循环,循环遍历一个关联数组。对于每个条目,我必须发出一个ajax请求,并用检索到的数据填充另一个数组。 问题是成功回调是异步的,因此它只在循环被迭代后运行。这意味着我的数据数组中填充了上一个ajax请求结果的多个副本。 这是我的代码(简化): var通道={ “错误”:“频道错误”, “计划”:“渠道计划” }; var数据//初始数据为空 函数getData(){ 数据=新数组(); 用于(通道中的var系列数据){ var currentData=新数组(); $.ajax({

我有一个for循环,循环遍历一个关联数组。对于每个条目,我必须发出一个ajax请求,并用检索到的数据填充另一个数组。
问题是成功回调是异步的,因此它只在循环被迭代后运行。这意味着我的数据数组中填充了上一个ajax请求结果的多个副本。 这是我的代码(简化):

var通道={
“错误”:“频道错误”,
“计划”:“渠道计划”
};
var数据//初始数据为空
函数getData(){
数据=新数组();
用于(通道中的var系列数据){
var currentData=新数组();
$.ajax({
键入:“获取”,
url:'http://'+serverAddress+':'+serverPort+'/GetChannelBufferAsJsonp?channelName='+channels[seriesData]+'&callback=?',
数据类型:“json”,
async:false,
成功:函数(json){
var time=new Date().getTime()+3600000;
for(var i=0;i
所以数据有两个元素(正确),但它们都来自“plan_channel”(即我的数据源)。 我知道这是ajax请求的一个经典的、众所周知的“问题”(或特性),但我不知道如何摆脱它。
你能告诉我如何等待成功回调结束,然后再进行下一次迭代吗?

这是我能看到的重构代码的唯一方法(我不知道)。不过这有点毫无意义。在我看来,你的设置全错了,你不应该那样做。我所能看到的最好的方法是在一个ajax请求中将整个数组发送到ajax脚本,在php(或其他)中处理所有数组,然后以javascript中所需的格式将其吐出。否则你最好找一个更好的方法。例如,您可以使用ajax请求来调用success调用中的
getData()
函数,而不是使用For循环

// add a global var...
var inLoop;
function getData() {
    data = new Array();

    for (var seriesData in channels) {
        inLoop = true; // set to true
        var currentData = new Array();

        $.ajax({
            type: "GET",
            url: 'http://' + serverAddress + ':' + serverPort + '/GetChannelBufferAsJsonp?channelName=' + channels[seriesData] + '&callback=?',
            dataType: "json",
            async: false,
            success: function (json) {
                // set inLoop to false to get out of loop below
                inLoop = false;
                var time = new Date().getTime() + 3600000;
                for (var i = 0; i < json.length; i++) {
                    currentData.push({
                        x: time + i * 30000,
                        y: json[i]
                    });
                }

                data.push({
                    id: seriesData,
                    name: "Production " + seriesData,
                    data: currentData
                });

            }, error: function () {
                console.log("error", this);
            }
        });

        // loop round this bit for a while
        while(inLoop){
          // wait
        }
    }


}

为了做到这一点,您可能需要计算通过函数或其他东西的次数,以便能够再次将下一个通道传递到函数。

对于同步AJAX调用,您不能使用成功处理程序,必须在调用完成后返回结果

尝试使用Amplify.js(http://amplifyjs.com/)asyc设置为false时;它比jqueryajax函数更易于使用和整洁。别被额外的图书馆耽搁了

更新#1

你必须这么做

function getData() {
    data = new Array();

    for (var seriesData in channels) {
        var currentData = new Array();


    amplify.request.define( "ajaxExample1", "ajax", {
        url: 'http://' + serverAddress + ':' + serverPort + '/GetChannelBufferAsJsonp?channelName=' + channels[seriesData] + '&callback=?',
        dataType: "json",
        async: false,
        type: "GET"
    });

    // later in code
    amplify.request( "ajaxExample1", function( json ) {
        var time = new Date().getTime() + 3600000;
        for (var i = 0; i < json.length; i++) {
            currentData.push({
                x: time + i * 30000,
                y: json[i]
            });
        }

        data.push({
            id: seriesData,
            name: "Production " + seriesData,
            data: currentData
        });
    });

    }
}
函数getData(){ 数据=新数组(); 用于(通道中的var系列数据){ var currentData=新数组(); amplify.request.define(“ajaxExample1”、“ajax”{ url:'http://'+serverAddress+':'+serverPort+'/GetChannelBufferAsJsonp?channelName='+channels[seriesData]+'&callback=?', 数据类型:“json”, async:false, 键入:“获取” }); //以后的代码 请求(“ajaxExample1”,函数(json){ var time=new Date().getTime()+3600000; for(var i=0;i
如果我理解您的问题,为什么不使用全局标志/布尔值来控制ajax请求何时启动?为什么不使用新数据清除数组中的数据呢?@FiveTools您可以演示如何将全局标志与for循环结合使用吗?我看不见。@ThomasClayson不,异步似乎不起作用。我已经设置好了,正如您从代码中看到的那样。@Eli这不会改变任何事情。请用答案代替评论。这就是stackoverflow的工作原理。我不会否决任何答案,所以不用担心。但是如果你有一段时间轮询变量,浏览器不会说“有一个脚本没有响应吗?”嗯,一般来说,我知道如何处理ajax请求,但在这个特定场景中,我无法改变我的“服务器”回答的方式,因为我在现场传感器方面有很大的硬件限制。无论如何,您的解决方案似乎不起作用,因为while循环永远不会结束(inLoop变量始终为true@EvilP嗯,这很有可能。不管怎么说,这很愚蠢,只是用一个while循环来暂停脚本。最好完全重写代码。@andreapier成功函数中的inLoop变量设置为false。但这不是编写代码的好方法。我建议重写并向
getData发送新请求来自ajax请求的success函数,而不是使用for循环。因此,如果使用.getData(),您有一个success函数,当ajax请求完成并“成功”时会调用该函数?您的编辑打开了我的心扉,谢谢。我还不错,这是一个很好的解决方案,也可以推广!
var channels = {
  "first" : "hello world",
  "second" : "goodbye world"
}

function getData(channel){
  $.ajax({
    url: 'http://whatever.com/channel='+channel,
    success: function(){
      getData(nextchannel);
    }
  });
}
function getData() {
    data = new Array();

    for (var seriesData in channels) {
        var currentData = new Array();


    amplify.request.define( "ajaxExample1", "ajax", {
        url: 'http://' + serverAddress + ':' + serverPort + '/GetChannelBufferAsJsonp?channelName=' + channels[seriesData] + '&callback=?',
        dataType: "json",
        async: false,
        type: "GET"
    });

    // later in code
    amplify.request( "ajaxExample1", function( json ) {
        var time = new Date().getTime() + 3600000;
        for (var i = 0; i < json.length; i++) {
            currentData.push({
                x: time + i * 30000,
                y: json[i]
            });
        }

        data.push({
            id: seriesData,
            name: "Production " + seriesData,
            data: currentData
        });
    });

    }
}