【问题标题】:Javascript for loop ajax potential race condition?循环ajax潜在竞争条件的Javascript?
【发布时间】:2014-11-02 00:39:21
【问题描述】:

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

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 值?

【问题讨论】:

  • 我建议将内部 for 循环中发生的事情创建为一个单独的函数,您可以将变量传递给。您可以使用闭包完成相同的操作,但不建议在循环中创建函数。这里有一些关于它的信息tobyho.com/2011/11/02/callbacks-in-loops

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


【解决方案1】:

你需要一个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);


    }
  }
}

【讨论】:

  • 我对此做了一个小修改,意识到您的回调不仅需要key,还需要file_url。您可以了解如何通过这种方式将尽可能多的范围传递给 IIFE
【解决方案2】:

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

让我给你一个回答你问题的基础;我将忽略文件的部分,以强调查看的位置。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-22
    • 2018-07-24
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多