我有一个for循环,在for循环中,我正在设置一个变量。同样,在同一个循环中,我正在做另一个循环并执行ajax调用。我的问题是,成功回调需要时间,因此我的变量在此期间会发生变化,从而产生错误。我创建了一个演示:
var items = [1, 2, 3, 4, 5, 6];
// I have a for here {
var item = items[i];
for (var i = 0; i < items.length; i++) {
$.ajax({
url: '/search',
dataType: "json",
success: function (data) {
console.log(item);
}
})
}
}
Item
同时返回相同的值
编辑:我尝试传递这样的值,但没有用:
$.ajax(item, {
url: '/search',
dataType: "json",
success: function (data, item) {
console.log(item);
}
})
答案 0 :(得分:3)
由于围绕var
关键字的疯狂范围规则,只有一个item
。您只是更改现有项目的值。
如果您的目标是支持ES6的环境,则可以改为使用关键字let
。
var items = [1, 2, 3, 4, 5, 6];
for (var i = 0; i < items.length; i++) {
let item = items[i];
$.ajax({
url: '/search',
dataType: "json",
success: function (data) {
console.log(item);
}
})
}
let
是块作用域,而var
是函数作用域。 let
关键字将确保每个循环都有不同的实例。
如果您想要一个适用于旧浏览器的解决方案:
var items = [1, 2, 3, 4, 5, 6];
for (var i = 0; i < items.length; i++) {
var item = items[i];
var handlerFunction = (function(item) {
return function(data) {
console.log(item);
}
})(item);
$.ajax({
url: '/search',
dataType: "json",
success: handlerFunction
})
}
在此解决方案中,我们创建了一个匿名函数并将item
传递给它。此函数中的item
参数属于此函数,并且不会被外部item
对象更改所改变。
您可以说&#34;但处理程序功能的范围也是var
关键字&#34;。但是没关系,因为在重新分配不同的匿名函数之前,循环的每次迭代handlerFunction
都作为参数传递给ajax
方法。
<小时/> 你的问题让我想问一下,如果必须生成以ES5为目标的javascript,打字稿如何处理循环中的块范围变量。
有趣的是,这段代码:
var items = [1, 2, 3, 4, 5, 6];
for (var i = 0; i < items.length; i++) {
let item = items[i];
window.setTimeout(function() {
console.log(`timeout function: item=${item}`);
}, 100);
}
编译为此javascript
var items = [1, 2, 3, 4, 5, 6];
var _loop_1 = function () {
var item = items[i];
window.setTimeout(function () {
console.log("timeout function: item=" + item);
}, 100);
};
for (var i = 0; i < items.length; i++) {
_loop_1();
}
因此,typescript编译器使用封闭函数来确保每个item
都是唯一的。