Heim  >  Fragen und Antworten  >  Hauptteil

javascript - js实现for循环1-10, 延迟500ms展示结果, 但结果总是错误的, 求办法

描述如题

代码如下

function test() {
  for(var i=0; i<10; i++) {
    setTimeout(function(){
      (function (m) {
        console.log(m);
      })(i)
    }, 500)
  }
}
test();

执行结果

请教下解决办法, 并指出错误位置, 谢谢!

PHP中文网PHP中文网2749 Tage vor1131

Antworte allen(15)Ich werde antworten

  • PHPz

    PHPz2017-04-11 12:07:17

    直接在setTimeout()里用即时执行封装下回调就行了,你封包在setTimeout()的里边跟没封区别不大:

    function test() {
      for(var i=1; i<11; i++) {
        setTimeout((function(){
            console.log(i);
        })(), 500)
      }
    }
    test();

    补充:

    如果想做成间隔500ms一次console.log,那我觉得不如直接写成:

    var i = 1;
    var ii = setInterval(function(){
        if (i<11) {
            console.log(i);
            i++;
        } else {
            clearInterval(ii);
        }
    }, 500);

    Antwort
    0
  • 高洛峰

    高洛峰2017-04-11 12:07:17

    题主之所以会出现此问题,完全是由于没有理解闭包

    es5之前js是没有块级作用域这个说法的

    可以通过()()来模拟块级作用域

    for(var i = 0; i < 10; i++) {
        setTimeout((function(){
            console.log(i)
        })(),500)
    }
    // 0 1 2 3 4 5 6 7 8 9

    es6通过let命令,声明变量只在书写的let命令代码块内有效
    所以 @radius 写的就复杂了

    for(let i=0; i<10; i++) {
        setTimeout(function(){
            console.log(i);
        }, 500)
    }
    // 0 1 2 3 4 5 6 7 8 9

    阮一峰es6块级作用域

    Antwort
    0
  • 迷茫

    迷茫2017-04-11 12:07:17

    function test() {
      for(var i=0; i<10; i++) {
        (function(i){
            setTimeout(function(){
                console.log(i);
            },500);
            })(i)
      }
    }
    test();
    
    
    这个是循环0-9   1-10你自己改

    Antwort
    0
  • PHPz

    PHPz2017-04-11 12:07:17

    function test() {
    for(var i = 1 ;i<=10;i++){

     (function(i){
         setTimeout(function(){
             console.log(i)
         },500)
     })(i);

    }
    }
    test();

    Antwort
    0
  • 大家讲道理

    大家讲道理2017-04-11 12:07:17

    function test(){

    for(var i = 0 ;i<10 ;i++){
        setTimeout((function(m){
            return function(){ console.log(m)}
        })(i),500);
    }

    }

    test();

    Antwort
    0
  • 阿神

    阿神2017-04-11 12:07:17

    function test() {
      for(var i=1; i<=10; i++) {
        setTimeout((function(m){
          return function () {
            console.log(m);
          }
        })(i), 500 * i)
      }
    }
    test();

    Antwort
    0
  • 大家讲道理

    大家讲道理2017-04-11 12:07:17

    function count() {
        var arr = [];
        for (var i=1; i<=3; i++) {
            arr.push(function () {
                return i * i;
            });
        }
        return arr;
    }
    
    var results = count();
    var f1 = results[0];
    var f2 = results[1];
    var f3 = results[2];

    在上面的例子中,每次循环,都创建了一个新的函数,然后,把创建的3个函数都添加到一个Array中返回了。

    你可能认为调用f1(),f2()和f3()结果应该是1,4,9,但实际结果是:

    f1(); // 16
    f2(); // 16
    f3(); // 16

    返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。
    廖雪峰教程:闭包

    Antwort
    0
  • 阿神

    阿神2017-04-11 12:07:17

    function test() {
      for(let i=0; i<10; i++) {
        setTimeout(function(){
          (function (m) {
            console.log(m);
          })(i)
        }, 500)
      }
    }
    test();

    只把var改成let就行了

    Antwort
    0
  • 天蓬老师

    天蓬老师2017-04-11 12:07:17

    setTimeout上修改:

    setTimeout(function(m) {
        console.log(m);
    })(i), 500);

    Antwort
    0
  • 迷茫

    迷茫2017-04-11 12:07:17

    es2016 or typescript:

    async function test() {
        var i = 0;
        for (i = 0; i < 10; i++) {
            await new Promise(resolve => setTimeout(resolve, 500));
            console.log(i);
        }
    }
    
    test();

    Antwort
    0
  • StornierenAntwort