javascript for循环中的异步进程

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (10)

我正在运行以下形式的事件循环:

var i;
var j = 10;
for (i = 0; i < j; i++) {

    asycronouseProcess(callBackFunction() {
        alert(i);
    });
}

我想要显示的是一系列显示数字0到10的警报。问题是,在触发回调函数时,循环已经进行了几次迭代,并且显示了更高的i值。对如何解决这个问题有什么建议吗?

提问于
用户回答回答于

=

使用.forEach()迭代,因为它创建了自己的函数闭包

someArray.forEach(function(item, i) {
    asynchronousProcess(function(item) {
        console.log(i);
    });
});

创建自己的函数闭包使用

var j = 10;
for (var i = 0; i < j; i++) {
    (function(cntr) {
        // here the value of i was passed into as the argument cntr
        // and will be captured in this function closure so each
        // iteration of the loop can have it's own value
        asynchronousProcess(function() {
            console.log(cntr);
        });
    })(i);
}

创建或修改外部函数,并将变量传递给它。

如果可以修改asynchronousProcess()函数,则可以将值传递到其中,并使asynchronousProcess()函数cntr返回回调,如下所示:

var j = 10;
for (var i = 0; i < j; i++) {
    asynchronousProcess(i, function(cntr) {
        console.log(cntr);
    });
}

使用ES6let

如果你有一个完全支持ES6的Javascript执行环境,则可以使用let在你的for这样的循环:

const j = 10;
for (let i = 0; i < j; i++) {
    asynchronousProcess(function() {
        console.log(i);
    });
}

letfor循环声明将创建一个唯一的值i对于循环的每次调用(这是您想要的)。

注意:这个ES6特性通常是JS引擎支持的后期ES6特性之一,因此你必须确保在您的环境中支持这个特定特性。

用户回答回答于

有关如何解决此问题的任何建议?

你可以使用bind

for (i = 0; i < j; i++) {
    asycronouseProcess(function (i) {
        alert(i);
    }.bind(null, i));
}

或者,如果你的浏览器支持let(它将在下一个ECMAScript版本,但Firefox已经支持它一段时间),你可以有:

for (i = 0; i < j; i++) {
    let k = i;
    asycronouseProcess(function() {
        alert(k);
    });
}

或者,你可以bind手动完成这项工作(如果浏览器不支持它,但是我会说你可以在这种情况下实现一个填充程序,它应该在上面的链接中):

for (i = 0; i < j; i++) {
    asycronouseProcess(function(i) {
        return function () {
            alert(i)
        }
    }(i));
}

我通常更喜欢let当我可以使用它(例如Firefox附加组件); 否则bind还是自定义的curry函数(不需要上下文对象)。

扫码关注云+社区