2012-02-13 53 views
0

我有一个用于循环,超过一个关联数组迭代。 foreach条目我必须做一个ajax请求,并用检索的数据填充另一个数组。
问题是成功回调是异步的,所以它只有在循环迭代后才运行。这意味着我的数据数组充满了最后一个Ajax请求结果的多个副本。 这是我的代码(简化):等待AJAX​​成功结束才去槽下一迭代

var channels = { 
    "misured": "channel_misured", 
    "plan": "channel_plan" 
}; 
var data; //Initial data is empty 

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

    for (var seriesData in channels) { 
     var currentData = new Array(); 
     $.ajax({ 
      type: "GET", 
      url: 'http://' + serverAddress + ':' + serverPort + '/GetChannelBufferAsJsonp?channelName=' + channels[seriesData] + '&callback=?', 
      dataType: "json", 
      async: false, 
      success: 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 
       }); 

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


} 

所以数据有2个元素(正确的),但他们都来自于“plan_channel”(这是我的数据源)。 我知道这是一个经典,众所周知的“问题”(或功能)的Ajax请求,但我不明白我可以摆脱它。
你可以告诉如何等待成功回调才能结束,然后再进行下一次迭代?
非常感谢

+0

如果我明白你的问题,为什么不使用一个全局标志/布尔你的Ajax请求启动时控制? – FiveTools 2012-02-13 14:54:57

+0

做异步:假不工作? – 2012-02-13 14:55:47

+0

而不是将数据推入数组为什么不用数据清除数组? – Eli 2012-02-13 14:57:55

回答

1

这是我能看到重构代码的唯一方法。尽管如此,它有点无意义。你已经设置了所有错误的海事组织,你不应该那样做。我可以看到这样做将是整个阵列中的一个Ajax请求发送到AJAX脚本,应对这一切在PHP(或其他)和吐回了格式的最佳方式,你希望它在JavaScript 。否则,你最好找到一个更好的方法来做到这一点。举个例子,如果不是有一个for循环,你可能会有一个ajax请求,它会在成功调用中回调函数getData()

// 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 
     } 
    } 


} 

这是我会怎样改写上面的代码:

var channels = { 
    "first" : "hello world", 
    "second" : "goodbye world" 
} 

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

为了做到这一点,你可能要算你走的时候通过函数或东西,以便能够通过下一个通道再次进入函数。

+0

但如果你有一段时间轮询变量没有浏览器说“有一个脚本没有响应?” – 2012-02-13 15:07:24

+0

嗯,我知道如何处理一般的Ajax请求,但在这个特殊的情况下我不能改变的方式我的“服务器”的答案,因为我有在现场传感器大范围的硬件。反正你的解决方案似乎并没有工作,因为while循环永远不会结束(中环内变量始终是真实 – andreapier 2012-02-13 15:10:55

+0

@EvilP嗯,多数民众赞成完全可能的。它的愚蠢反正只是拖延while循环脚本。它更好地完全重写该代码。 @andreapier inLoop var在成功函数中设置为false。但它不是编写代码的好方法。我建议从ajax请求的成功函数中重写并发送一个新的请求到'getData',而不是使用for循环。 – 2012-02-13 15:14:29

1

对于同步AJAX调用您不能使用成功处理程序,一旦您的通话已完成必须返回结果。

尝试使用Amplify.js(http://amplifyjs.com/)设置为false的ASYC;它比jQuery ajax功能更容易使用,更加简洁。不要被额外的图书馆推迟。

更新#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 
     }); 
    }); 

    } 
} 
+0

这个图书馆看起来不错,我会试试。 – andreapier 2012-02-13 15:49:49