循环内的异步

问题描述:

我使用jQuery的$.getJSON() API从一组实用程序的给定URL检索数据。我真的很想找到一种方法来重用每个实用程序的代码(完全一样)。由于循环执行时不考虑ajax调用,因此我无法找到保留循环值的方法。循环内的异步

这说明很烂,我知道,所以here'a定义它的代码片断好一点:

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个循环都针对“水”工具执行。我知道为什么它是而不是工作,我只是想知道是否有一个合理的解决方法。

谢谢。

创建一个封闭

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

这样做,同时仍使用匿名闭合的规范的方法是创建立即调用,并通过循环变量,然后一个匿名闭包回报的真正的回调。

这个匿名封闭件具有其自身的范围包含其自己的变量(包括传递的参数),其可以覆盖外循环的变量,例如:

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

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

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

可以分配的“类型”值来为每个AJAX请求的成员变量,并使用在回调成功函数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; 
}