JavaScript异步回调和范围

Igo*_*lyk 13 javascript scope asynchronous callback

请考虑以下示例:

var cb = function (t) {
    console.log('callback -->' + t);
};

for(var i = 0; i<3; i++) {
    console.log(i);
    setTimeout(function(){
        cb(i);
    },1000);
}
Run Code Online (Sandbox Code Playgroud)

jsfiddle的工作示例

此代码段的输出是:

0
1
2
callback ---> 3
callback ---> 3
callback ---> 3
Run Code Online (Sandbox Code Playgroud)

一切都按预期工作,for循环将3个回调调用放入事件循环.在for循环结束时i == 3并且当回调被执行时,所有这些都打印3,因为它们包含到i的链接,即3.如何改进此代码片段以便在回调执行时它使用实际传递给它的价值.

输出应该是:

callback ---> 1
callback ---> 2
callback ---> 3
Run Code Online (Sandbox Code Playgroud)

提前致谢.

Jos*_*eph 18

创建一个闭包,以便setTimeout处理程序将引用闭包的局部变量(在本例中,我们也命名i),而不是i来自循环:

for (var i = 0; i < 3; i++) {
    (function (i) {
        console.log(i);
        setTimeout(function () {
            cb(i);
        }, 1000);
    }(i));
}
Run Code Online (Sandbox Code Playgroud)


xda*_*azz 6

你可以试试.bind:

for(var i = 0; i<3; i++) {
    console.log(i);
    setTimeout(cb.bind(null, i),1000);
}
Run Code Online (Sandbox Code Playgroud)

演示.

处理此问题的传统方法是创建一个闭包:

for(var i = 0; i<3; i++) {
    console.log(i);
    setTimeout((function(i){return function(){cb(i)}}(i)),1000);
}
Run Code Online (Sandbox Code Playgroud)