循环内的异步
问题描述:
我使用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;
}