javascript - js实现for循环1-10, 延迟500ms展示结果, 但结果总是错误的, 求办法
PHP中文网
PHP中文网 2017-04-11 12:05:17
0
15
1116

描述如题

代码如下

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

执行结果

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

PHP中文网
PHP中文网

认证高级PHP讲师

全部回复(15)
PHPzhong

直接在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);
小葫芦

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

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块级作用域

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


这个是循环0-9   1-10你自己改
PHPzhong

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

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

}
}
test();

大家讲道理

function test(){

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

}

test();

阿神
function test() {
  for(var i=1; i<=10; i++) {
    setTimeout((function(m){
      return function () {
        console.log(m);
      }
    })(i), 500 * i)
  }
}
test();
大家讲道理
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

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

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

只把var改成let就行了

Peter_Zhu

setTimeout上修改:

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

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();
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责声明 Sitemap
PHP中文网:公益在线PHP培训,帮助PHP学习者快速成长!