2014-11-02 45 views
0

这里有一个简单的循环,我跑:Javascript for循环ajax潜在的竞争条件?

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); 
     }); 
    } 
    } 
} 

的问题是,key值始终是由当时的一样JSON请求完成。如何避免这种竞争条件,以便在$.getJSON完成时使用正确的key值?

+2

我建议建立的东西在内部发生的for循环作为一个单独的功能,您可以通过变量。你可以使用闭包完成相同的操作,但不建议在循环中创建函数。这里有一些关于它的信息http://tobyho.com/2011/11/02/callbacks-in-loops/ – Lbatson 2014-11-02 00:55:12

回答

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); 


    } 
    } 
} 
+0

我做了一个小编辑,实现你的回调不仅需要'key',还需要'file_url'。您可以看到如何以这种方式将足够的范围传递给IIFE – 2014-11-02 01:23:25

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