Javascript for循环ajax潜在竞争条件?

时间:2014-11-02 00:39:22

标签: javascript jquery ajax for-loop race-condition

这是一个我正在运行的简单循环:

for (var key in TestApp.config.services) {
  if (TestApp.config.services[key].files != "") {
    var files = TestApp.config.services[key].files.split(',');
    for (var i = 0; i <= files.length - 1; i++) {
      var file_url = files[i];
      console.log("About to download :" + file_url);
      $.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent(file_url) + '&callback=?', function(data) {
        console.log("Downloaded file: " + file_url);
        console.log(key);
      });
    }
  }
}

问题是JSON请求完成时key值始终相同。如何避免此竞争条件,以便在key完成时使用正确的$.getJSON值?

2 个答案:

答案 0 :(得分:2)

您需要Immediately-invoked function expression (IIFE)

for (var key in TestApp.config.services) {
  if (TestApp.config.services[key].files != "") {
    var files = TestApp.config.services[key].files.split(',');
    for (var i = 0; i <= files.length - 1; i++) {
      var file_url = files[i];
      console.log("About to download :" + file_url);

      // IIFE
      (function(thiskey,this_file_url){
          $.getJSON('http://whateverorigin.org/get?url=' + encodeURIComponent(this_file_url) + '&callback=?', function(data) {
            console.log("Downloaded file: " + this_file_url);
            console.log(thiskey);
          });
      })(key,file_url);


    }
  }
}

答案 1 :(得分:-1)

一个简单的解决方案是简单地发送带有请求的密钥。我更喜欢用{}符号写出来。

让我给你答案的基础;我将忽略文件中的部分,以强调在哪里查看。

的index.php

<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script>
  var items = ['Hello', 'World', 'foo', 'bar'];
  for (var i=0; i < items.length; i++) {
    console.log("About to download :" + items[i] + '" - key: ' + i);
    $.getJSON( "ajax.php", 
      {
        url: items[i],
        key: i
      },
      function(data) {
        var key = data.key;
        console.log("Downloaded file: " + data.url + '" - key: ' + key);
      }
    );
  }
</script>

ajax.php

<?php
echo json_encode(array('url'=>$_GET['url'], 'key'=>$_GET['key']));
?>