循环中的异步性

时间:2011-03-19 16:34:01

标签: jquery ajax

我正在使用jQuery的$.getJSON() API从一组实用程序的给定URL中检索数据。我真的想找到一种方法来重用每个实用程序的代码(它们都完全相同)。由于循环正在执行而不考虑ajax调用,因此我无法找到保留循环值的方法。

这个描述很糟糕,我知道,所以这里是一个代码片段,它更好地定义了它:

var utility_types = [ 'Electricity', 'Gas', 'Water' ];

/** Retrieve known utility providers for the given zip code */
for( var i = 0; i < utility_types.length; i++ ) {
  var type = utility_types[i];

  $.getJSON( '/addresses/utilities/' + zip + '/' + type + '.json', null, function( data, status ) {
    alert( 'Processing ' + type );
  });
}

我需要找到一种方法将类型值传递给回调,以便我可以应用正确的语法。没有它,所有3个循环都在针对“Water”实用程序执行。我知道为什么正在工作,我只是想知道是否有合理的解决方法。

感谢。

3 个答案:

答案 0 :(得分:4)

创建一个闭包

var utility_types = [ 'Electricity', 'Gas', 'Water' ];

function getCallBack(type){
   return function(data,status){
     alert( 'Processing ' + type );
   }
}

/** Retrieve known utility providers for the given zip code */

for( var i = 0; i < utility_types.length; i++ ) {
  var type = utility_types[i];

  $.getJSON( '/addresses/utilities/' + zip + '/' + type + '.json', null, getCallBack(type));
}

答案 1 :(得分:3)

在使用匿名闭包的同时执行此操作的规范方法是创建一个 new 匿名闭包,立即调用并传递循环变量,然后返回真实回调。

这个匿名闭包有自己的作用域,它包含自己的变量(包括传递的参数),它可以覆盖外部循环的变量,例如:

..., success: (function(type) {
    return function() {
        alert(type);
    }
}(type))

外部括号中的type是循环变量。函数声明中的type参数,它位于新闭包的范围内。调用alert时,它使用范围最接近的那个,即参数。

当然,参数可以有自己的变量名,它不必与外部作用域中的变量名相同!如果它不同,则两者都可用,但外部范围的版本将始终具有相同的值。

答案 2 :(得分:0)

您可以为每个ajax请求的成员变量分配'type'值,并使用回调成功函数中的this关键字对其进行测试:

var utility_types = [ 'Electricity', 'Gas', 'Water' ];

/** Retrieve known utility providers for the given zip code */
for( var i = 0; i < utility_types.length; i++ ) {
  var type = utility_types[i];

  var jsonReq = $.getJSON( '/addresses/utilities/' + zip + '/' + type + '.json', null, function( data, status ) {
    alert( 'Processing ' + this.utilityType );
  });
  jsonReq.utilityType = type;
}