Ajax需要时间,因此获得错误的变量值

时间:2016-12-14 05:11:15

标签: javascript jquery asynchronous

我有一个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);
        }
     })

1 个答案:

答案 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都是唯一的。