关于javascript:setTimeout并将变量一起传递给匿名函数

setTimeout and passing variables to anonymous function together

本问题已经有最佳答案,请猛点这里访问。

我正在写一个代码,我坚持使用setTimeout函数。 我想获得动画效果。 显示延迟的数组元素。 代码完成了。

1
2
3
4
5
6
7
for (var i=0;i <= array.length-1;i++) {
                        (function(el) {
                            setTimeout(function(){
                             document.getElementById('Result').innerHTML += Math.floor(el);
                             console.log(Math.floor(el));
                            }, 3000*(i+1));
                        })(array[i]);

当我使用for (var i=array.length-1; i>=0;i--)为什么时,我有延迟问题? (这个代码的想法是显示项目数组从最后到第一个)

1
2
3
for (var i=0;i <= array.length-1;i++) {
                        (function(el) {
                            setTimeout(function(){

现在给出相同的结果:for (var i=array.length-1; i>=0;i--) {
console.log(array[i]+'!')


这里的问题是关闭。闭包是一种匿名函数,用于记住在异步函数中使用它们的参数(如setTimeout)。

如果你把类似的东西

1
setTimeout(function(foo){...}(value), 3000)

在创建setTimeout之前调用该函数。所以你必须使用一个闭包来做到这一点:

1
2
3
4
5
(function(foo){
    setTimeout(function() {
        ... do something with foo ...
    }, 3000);
})(value_of_foo);

此代码将记住foo的值,以使用使用它的函数创建setTimeout。

另一个问题是你必须增加setTimeout时间来创建延迟,否则for将创建一堆setTimeout(..., 3000),它将一次执行。那么您需要对代码执行的操作如下:

1
2
3
4
5
6
7
for (var i=array.length-1; i>=0;i--) {
    (function(el) {
        setTimeout(function(){
            document.getElementById('Result').innerHTML += Math.floor(el)
        }, 3000*(array.length-i));
    })(array[i]);
}

在主函数完成之后才会执行超时,这意味着在每个循环执行超时函数时,i变量将处于其最终值(在本例中为= 0)。您的函数声明也不正确,因为超时函数没有为您传递这些参数。要做到这一点,你需要将你的超时包装在另一个函数调用中,该函数调用接受当前循环的参数,尝试这样的事情......

1
2
3
4
5
6
7
for (var i=array.length-1; i>=0;i--) {
  function(array, i) {
    setTimeout(function() {
      document.getElementById('Result').innerHTML += Math.floor(array[i]);
    }, (i+1) * 3000);
  }(array, i);
}


首先,您立即调用该函数,并将其结果指定为超时的回调。 (这是错误的,因为第一个参数必须是函数)

然后,您有一些语法错误,缺少关闭}) ..

尝试

1
2
3
4
5
6
7
for (var i=array.length-1; i>=0;i--) {
    function(array,i){
        setTimeout(function(){
            document.getElementById('Result').innerHTML += Math.floor(array[i]);
        }, 3000*i);
    }(array,i);
}

我使用了3000*i,因此每个超时都是另一个超时后3秒