search

Home  >  Q&A  >  body text

JavaScript 循环加载定时器的问题

<script type="text/javascript">
for(var i=0;i<3;i++){
	
	setTimeout(function(){
		alert(i);
	},10000);
}
</script>

以上代码每次都是弹出3,我想延时依次弹出 1、2、3 不知道怎么做?

天蓬老师天蓬老师2818 days ago648

reply all(4)I'll reply

  • 阿神

    阿神2017-04-10 12:45:38

    楼主的代码加上问题说明..有点难以揣测其目的..

    1、如果是延迟10s,立刻弹出1、2、3,从“延迟”这个词只出现一次来看,只要一个定时器就够了,并不需要循环创建三个定时器,所以代码应该是:

    setTimeout(function() {
    	for(var i = 1; i < 4; i++) {
    		console.log(i);
    	}
    }, 10000);

    而忠邦君的代码相当于

    setTimeout(function() {alert(1);}, 1000);
    setTimeout(function() {alert(2);}, 1000);
    setTimeout(function() {alert(3);}, 1000);

    因为@felix021 同学所说的调度算法的原因,三个定时器几乎同时创建后其中的函数执行的顺序是不一定的,所以什么可能性都会有...不要相信那真的是1000ms.....

    2、如果是延迟10s,弹出1,再延迟10s,弹出2,再延迟10s,弹出3,那是要三个定时器的,比如@felix021 的递归代码。

    换个思路也可以是:

    //var t = new Date();
    for (var i = 1; i < 4; i++) {
    	! function(_i) {
    		setTimeout(function() {
    			//console.log(t - (t = new Date()));
    			console.log(_i);
    		}, _i * 10000);
    	}(i)
    }

    3、如果只是为了调试,不要用alert,会阻塞,从而产生与实际不符的情况。

    reply
    0
  • 阿神

    阿神2017-04-10 12:45:38

    var counter = 0;
    function incr() {
        counter += 1; 
        alert(counter);
        if (counter < 3)
            setTimeout("incr()", 1000);
    }
    setTimeout("incr()", 1000);

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 12:45:38

    出现输出333的原因是,在循环中定义的函数,实际上,只创造了一个。而出现333这个原因更重要的一点是,函数中引用的是i这个变量,而不是i这个变量的值。
    有两种方法解决这个问题。

    Function Generator

    见@Fakefish 的回答。通过闭包可以在循环中创建多个定义的函数,更重要的是,传入的引用i为当前循环点的数值。但是由于setTimeout函数的实现问题,时间间隔并不是严格确定的,所以产生了@Fakefish 所看到的132输出。

    Define Function outside the loop

    var count = 0, i;
    var anonymous = function() {
      count++;
      console.log(count);
    };
    for(var i=0;i<3;i++){
      setTimeout(anonymous, 10000);
    }

    参考资料

    Creating A Javascript Function Inside A Loop http://blog.jbrantly.com/2010/04/crea...
    Arguments to JavaScript Anonymous Function http://stackoverflow.com/questions/30...

    reply
    0
  • PHP中文网

    PHP中文网2017-04-10 12:45:38

    for(var i=1;i<=3;i++){  
    (function(i){
        setTimeout(function(){
        	alert(i);
        },1000);
    })(i);
    }

    延时1秒正确,但是延时10秒答案就成1 3 2了.这个要去研究研究了.

    reply
    0
  • Cancelreply