用于循环ajax潜在竞争条件的Javascript

Javascript for loop ajax potential race condition?

本文关键字:条件 Javascript 竞争 循环 ajax 用于      更新时间:2023-09-26

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

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的值总是相同的。如何避免这种竞争条件,以便在$.getJSON完成时使用正确的key值?

您需要一个立即调用的函数表达式(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);

    }
  }
}

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

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

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']));
?>