如何在循环中的回调中引用`i`的正确值?

mar*_*zzz 4 javascript

我有这个代码:

for (var i = 0; i < result.length; i++) {
    // call a function that open a new "thread"
    myObject.geocode({ param1: "param" }, function(results, status) {
        alert(result.title[i]);
    });                                             
}
Run Code Online (Sandbox Code Playgroud)

.geocode函数(不是我的,所以我无法编辑)打开一个新的执行"线程".

当我尝试在每一步上打印标题时,我总是得到最后一个可能值i.

如何i为每次迭代保留对正确值的引用?

Mat*_*att 5

你可以在循环中创建一个闭包;

for (var i = 0; i < result.length; i++) {
    // call a function that open a new "thread"
    (function (i) {
        myObject.geocode({ param1: "param" }, function(results, status) {
            alert(result.title[i]);
        });
    }(i));                                             
}
Run Code Online (Sandbox Code Playgroud)

所以我们在这里创建一个函数;

(function (i) {
    myObject.geocode({ param1: "param" }, function(results, status) {
        alert(result.title[i]);
    });
});
Run Code Online (Sandbox Code Playgroud)

...接受一个名为的参数i,并启动地理编码请求.通过在(i)函数表达式的声明的末尾添加,我们立即运行该函数并将其传递给当前值i.

(function (i) {
    myObject.geocode({ param1: "param" }, function(results, status) {
        alert(result.title[i]);
    });
}(i));
Run Code Online (Sandbox Code Playgroud)

变量i已经存在于比闭包更高的范围内并不重要,因为本地声明i会覆盖它.我们传递闭包的变量,或者闭包调用变量的名称可能不同;

(function (anotherVariable) {
    myObject.geocode({ param1: "param" }, function(results, status) {
        alert(result.title[anotherVariable]);
    });
}(aVariable));
Run Code Online (Sandbox Code Playgroud)

或者你也可以将逻辑提取到另一个函数(我更喜欢它,但它不那么):

function geocode(i) {
   myObject.geocode({ param1: "param" }, function(results, status) {
       alert(result.title[i]);
   });
}

for (var i = 0; i < result.length; i++) {
    geocode(i);                                            
}
Run Code Online (Sandbox Code Playgroud)

问题在于回调函数使用的同一个 i变量; 正如您所发现的那样,在回调执行时已经移动了.上述两种解决方案都为每次迭代创建了另一个变量,这就是回调操作.