在我正在编写的chrome扩展中,我需要验证我在localStorage中存储的一些对象对我的服务器。为此,我创建了一个for循环,它只是为每个localstorage元素发送数据,并且需要对响应执行某些操作。代码是这样的:
for (var key in localStorage) {
if (! some condition )
continue;
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if (httpRequest.readyState === 4 && httpRequest.response == 200) {
do something with 'key' from the for loop
}
}
};
var url = BASE_PATH ;
httpRequest.open("POST", url);
httpRequest.send(some data);
}
然而,在调试时,似乎在ajax响应中,来自for循环的'key'不是我需要的密钥:我期望从for循环中获得与每个ajax调用匹配的相同密钥,我是什么得到的是所有ajax调用的相同密钥。 我做错了什么或期待一些不可能的事情?我认为,因为ajax在一个闭包函数中,所以这些值保存在内存或类似的东西中。
答案 0 :(得分:1)
将实际的Ajax调用解压缩到一个单独的函数:
function AjaxCall( key ) {
var httpRequest = new XMLHttpRequest();
httpRequest.onreadystatechange = function() {
if ((httpRequest.readyState === 4) && (httpRequest.response == 200)) {
do something with 'key' from the for loop
}
};
var url = BASE_PATH ;
httpRequest.open("POST", url);
httpRequest.send(some data);
}
for (var key in localStorage) {
if ( some condition ) {
AjaxCall( key );
}
}
原因是,您正在创建一个传递给onreadystatechange
的函数的闭包。所有这些函数都指向相同的key
变量,在循环结束后,它只保存所有Ajax调用的一个(最后一个)值。
当你创建一个单独的函数(比如我的例子中的AjaxCall()
)时,你会为每个调用创建一个不同的上下文,因此所有回调都指向不同的键。