settimeout中的随机计时器(for for循环)不准确

时间:2017-11-16 12:29:33

标签: javascript jquery settimeout

					for (var i = 0; i <= 10; i++) { setTimeout(function(ind) { return function() { 
							let start = Date.now()


								$('.output').append(
										"<div class=\"notify_box\">THIS IS THE BOX NUMBER"+ind+"</div>"
									).hide().fadeIn(1000);

								// fadeout / remove existing notify box  (3 seconds) and call another box 
								setTimeout(function(){ 
									$('.notify_box').fadeOut("slow")
								}, 2000);

							console.log(Date.now() - start)		
					}; }(i), Math.round(Math.random() * (5000 - 3000)) + 3000 *i);  } 
		.notify_box {
			background:  #9782AF;
			color: #ffffff;
			padding: 8px;
			border-radius: 20px;
			width: 30%;
			position: fixed;
		    margin: 0 10px 10px 0;
		}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="output"></div>

这是我的jsfiddle:https://jsfiddle.net/gsfe6vm9/

在第15行,木材似乎不准确。我把它设置为随机循环3到5秒,但有时会弹出1或2秒。

我怎样才能在它弹出的时候调试console.log?第14行似乎不正确。

这是我使用的代码:

for (var i = 0; i <= 10; i++) {
    setTimeout(function (ind) {
        return function () {
            let start = Date.now()

                $('.output').append(
                    "<div class=\"notify_box\">THIS IS THE BOX NUMBER" + ind + "</div>").hide().fadeIn(1000);

            // fadeout / remove existing notify box  (3 seconds) and call another box
            setTimeout(function () {
                $('.notify_box').fadeOut("slow")
            }, 2000);

            console.log(Date.now() - start)
        };
    }(i), Math.round(Math.random() * (5000 - 3000)) + 3000 * i);
}

1 个答案:

答案 0 :(得分:1)

我希望凭借这些知识,你可以解决你的问题。

&#13;
&#13;
for(var i = 1; i < 4; i++) { 
    setTimeout(function() { 
        console.log(i + " second(s) elapsed"); 
    }, i * 1000); 
}
&#13;
&#13;
&#13;

上面的代码可能用于输出以下消息,每条消息之间有一秒延迟:

1 second(s) elapsed
2 second(s) elapsed
3 second(s) elapsed

但是代码实际上输出了以下内容:

4 second(s) elapsed
4 second(s) elapsed
4 second(s) elapsed

问题是console.log(i +&#34;秒过了&#34;);是在异步函数的回调中。运行时,for循环已经终止,变量i将等于4

这个问题有各种解决方法,但最常见的是在闭包中包含对setTimeout的调用,这将在每次迭代中创建一个具有不同i的新作用域:

&#13;
&#13;
for(var i = 1; i <= 3; i++) {
    (function (i) { 
       setTimeout(function() {
           console.log(i + " second(s) elapsed"); 
       }, i * 1000); 
    })(i); 
}
&#13;
&#13;
&#13;

如果您使用的是ECMAScript6或更高版本,那么更优雅的解决方案是使用let代替var,因为let会为每个i创建一个新范围迭代:

&#13;
&#13;
for(let i = 1; i <= 3; i++) {
    setTimeout(function() {
        console.log(i + " second(s) elapsed"); 
    }, i * 1000);
}
&#13;
&#13;
&#13;

hack.guides()

了解详情