Nodejs环境下时间处理疑惑:一直不明白时间怎么变快了
Nodejs环境下时间处理疑惑:一直不明白时间怎么变快了
今天突然想到在js中随机填充100个div要多久,所以就试了试,结果引发一个我很想不明白的问题,坛子里应该有人明白,所以就贴出来大家给看看!
<!doctype html>
<html>
<head>
<title>test</title>
<style type="text/css">
.main{
width:600px;
height:500px;
margin:10px auto;
border:1px solid #ccc;
}
.item{
width:50px;
height:20px;
line-height:20px;
border:1px solid #ccc;
float:left;
margin:2px 2px;
}
</style>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript">
function GetColor(){
var str = "0123456789abcdef";
var t = "#";
for(j=0;j<6;j++)
{
t = t+ str.charAt(Math.random()*str.length);
}
return t;
}
var arr = new Array();
var i=0;
function setColor(){
var num = parseInt(Math.random()*(100-1+1)+1);
var t=0;
if(arr.length == 100){
$("div").css("background-color", "#ffffff");
i = 0;
arr = [];
}
if(i==0){
arr[i] = num;
i++;
}else{
for(var j=0;j<arr.length;j++){
if(num == arr[j]){
t++;
}
}
if(t>0){
setColor();
}else{
arr[i] = num;
console.log('i:' +i + ' num:'+num);
i++;
}
}
var id ="#d"+num;
var color = GetColor();
//$("div").css("background-color", "#ffffff");
$(id).css("background-color", "#333333");
setTimeout("setColor()", 500);
}
</script>
</head>
<body onload="setColor()">
<div class="main">
<div id="d1" class="item"> </div>
<div id="d2" class="item"> </div>
<div id="d3" class="item"> </div>
<div id="d4" class="item"> </div>
<div id="d5" class="item"> </div>
<div id="d6" class="item"> </div>
<div id="d7" class="item"> </div>
<div id="d8" class="item"> </div>
<div id="d9" class="item"> </div>
<div id="d10" class="item"> </div>
<div id="d11" class="item"> </div>
<div id="d12" class="item"> </div>
<div id="d13" class="item"> </div>
<div id="d14" class="item"> </div>
<div id="d15" class="item"> </div>
<div id="d16" class="item"> </div>
<div id="d17" class="item"> </div>
<div id="d18" class="item"> </div>
<div id="d19" class="item"> </div>
<div id="d20" class="item"> </div>
<div id="d21" class="item"> </div>
<div id="d22" class="item"> </div>
<div id="d23" class="item"> </div>
<div id="d24" class="item"> </div>
<div id="d25" class="item"> </div>
<div id="d26" class="item"> </div>
<div id="d27" class="item"> </div>
<div id="d28" class="item"> </div>
<div id="d29" class="item"> </div>
<div id="d30" class="item"> </div>
<div id="d31" class="item"> </div>
<div id="d32" class="item"> </div>
<div id="d33" class="item"> </div>
<div id="d34" class="item"> </div>
<div id="d35" class="item"> </div>
<div id="d36" class="item"> </div>
<div id="d37" class="item"> </div>
<div id="d38" class="item"> </div>
<div id="d39" class="item"> </div>
<div id="d40" class="item"> </div>
<div id="d41" class="item"> </div>
<div id="d42" class="item"> </div>
<div id="d43" class="item"> </div>
<div id="d44" class="item"> </div>
<div id="d45" class="item"> </div>
<div id="d46" class="item"> </div>
<div id="d47" class="item"> </div>
<div id="d48" class="item"> </div>
<div id="d49" class="item"> </div>
<div id="d50" class="item"> </div>
<div id="d51" class="item"> </div>
<div id="d52" class="item"> </div>
<div id="d53" class="item"> </div>
<div id="d54" class="item"> </div>
<div id="d55" class="item"> </div>
<div id="d56" class="item"> </div>
<div id="d57" class="item"> </div>
<div id="d58" class="item"> </div>
<div id="d59" class="item"> </div>
<div id="d60" class="item"> </div>
<div id="d61" class="item"> </div>
<div id="d62" class="item"> </div>
<div id="d63" class="item"> </div>
<div id="d64" class="item"> </div>
<div id="d65" class="item"> </div>
<div id="d66" class="item"> </div>
<div id="d67" class="item"> </div>
<div id="d68" class="item"> </div>
<div id="d69" class="item"> </div>
<div id="d70" class="item"> </div>
<div id="d71" class="item"> </div>
<div id="d72" class="item"> </div>
<div id="d73" class="item"> </div>
<div id="d74" class="item"> </div>
<div id="d75" class="item"> </div>
<div id="d76" class="item"> </div>
<div id="d77" class="item"> </div>
<div id="d78" class="item"> </div>
<div id="d79" class="item"> </div>
<div id="d80" class="item"> </div>
<div id="d81" class="item"> </div>
<div id="d82" class="item"> </div>
<div id="d83" class="item"> </div>
<div id="d84" class="item"> </div>
<div id="d85" class="item"> </div>
<div id="d86" class="item"> </div>
<div id="d87" class="item"> </div>
<div id="d88" class="item"> </div>
<div id="d89" class="item"> </div>
<div id="d90" class="item"> </div>
<div id="d92" class="item"> </div>
<div id="d93" class="item"> </div>
<div id="d94" class="item"> </div>
<div id="d95" class="item"> </div>
<div id="d96" class="item"> </div>
<div id="d97" class="item"> </div>
<div id="d98" class="item"> </div>
<div id="d99" class="item"> </div>
<div id="d91" class="item"> </div>
<div id="d100" class="item"> </div>
</div>
</body>
</html>
需要jquery文件
结果如图:
问题就在这里:刚开始的时候还是慢慢的增加,可是后面却一下变的很快,我设置的500毫秒不起作用了!请问各位大神怎么回事啊??不是应该一直都是500毫秒增加一个吗(不算迭代耗时)?????
您提到的时间处理问题可能与JavaScript的事件循环机制有关。在您的代码中,setTimeout("setColor()", 500)
是用来每隔500毫秒调用一次 setColor
函数的。然而,由于每次调用 setColor
时都会递归地再次调用自身,这可能会导致一些意外的行为。
示例代码分析
首先,我们来看一下您的代码中的关键部分:
function setColor(){
var num = parseInt(Math.random() * (100 - 1 + 1) + 1);
if (arr.length == 100) {
$("div").css("background-color", "#ffffff");
i = 0;
arr = [];
}
// 其他逻辑...
setTimeout("setColor()", 500);
}
问题分析
-
递归调用:
setTimeout("setColor()", 500)
实际上是一个递归调用,每次调用setColor
都会重新启动一个新的定时器。这意味着如果setColor
的执行时间超过了500毫秒,新的定时器会被立即启动,导致多个定时器同时运行。 -
事件循环:JavaScript 使用单线程和事件循环模型,这意味着如果某个函数执行时间过长,它会阻塞其他任务的执行。这可能导致后续的
setTimeout
被提前触发。
解决方案
为了确保每个 setTimeout
按照预期的方式工作,可以使用 setTimeout
的非字符串形式,并且确保每次调用 setColor
时不会重复启动新的定时器。
function setColor(){
var num = parseInt(Math.random() * (100 - 1 + 1) + 1);
if (arr.length == 100) {
$("div").css("background-color", "#ffffff");
i = 0;
arr = [];
}
// 其他逻辑...
setTimeout(setColor, 500); // 使用函数引用而非字符串
}
// 启动初始调用
setTimeout(setColor, 500);
进一步优化
为了避免重复调用 setColor
,可以在每次调用时检查是否已经有定时器在等待:
let timeoutId;
function setColor(){
var num = parseInt(Math.random() * (100 - 1 + 1) + 1);
if (arr.length == 100) {
$("div").css("background-color", "#ffffff");
i = 0;
arr = [];
}
// 其他逻辑...
if (timeoutId) {
clearTimeout(timeoutId);
}
timeoutId = setTimeout(setColor, 500);
}
// 启动初始调用
setTimeout(setColor, 500);
通过这种方式,您可以确保每次调用 setColor
时只有一个定时器在等待,从而避免了多次调用的问题。
settimeout的参数写错了
应该是逻辑问题,不过显示效果很好,收了。。。
不知道你要的效果是什么效果,但是显然这个循环调用时永远没办法停止的。当已经黑的div超过100的时候,还会继续跳帧,让白的变黑,黑的变白,反反复复,就算是jquery,也不是多个元素同步进行变化,微小的时间里还是按照堆栈顺序执行。就会出现后面的快速闪烁。如果你把时间设置为5000毫秒,然后观察,到后期依然会跳的很快,但是你会发现,即使你眼睛看到的5秒内跳速很快,但是5秒的间隔时间里还是会有停顿的。5秒时间里,随着循环数变大,使得你的变化div量增多,动画堆栈堆积迅速执行产生的残影~
for(var j=0;j<arr.length;j++){
if(num == arr[j]){
t++;
}
}
if(t>0){
setColor();
}else{
arr[i] = num;
console.log('i:' +i + ' num:'+num);
i++;
}
是这段代码的问题,你是通过setColor()来变换颜色的,带是这段就是在setColor()函数里面的,也就是说,有可能在调用setColor()函数时,又嵌套地调用了多次setColor()函数,然后又有可能继续嵌套调用setColor(),说不定浏览器都被搞死了。
就是没有打算停止,每500ms增加一个,当全部变成黑色之后在全部变回白色,从头开始,但是结果却完全不是!
浏览器确实越来越慢,但是不是有500ms限制了吗??三楼说的有点深奥,难道真的是”视觉残留“
这样改:
<script type=“text/javascript”>
Array.prototype.S = String.fromCharCode(2);
Array.prototype.in_array = function(e) {
var r = new RegExp(this.S+e+this.S);
return (r.test(this.S+this.join(this.S)+this.S));
};
function GetColor(){
var str = "0123456789abcdef";
var t = "#";
for(j=0;j<6;j++) {
t = t+ str.charAt(Math.random()*str.length);
}
return t;
}
var arr = new Array();
function setColor(){
var num = parseInt(Math.random()*(100-1+1)+1);
if(arr.length == 100){
$(“div”).css(“background-color”, “#ffffff”);
arr = [];
}
if(arr.in_array(num)){
setColor();
}else{
arr.push(num);
var id ="#d"+num;
var color = GetColor();
$(id).css(“background-color”, “#333333”);
}
}
function init(){
setInterval(“setColor()”, 500);
}
</script>
调用init(); 你那个setcolor()里判断完已经设置过颜色后,马上又调用了setcolor();又没有return;到后面设置过颜色的div越多,那进入这个分支的几率越大,所以到后面越来越快,而且程序执行的顺序也乱了。
果然厉害!
在你的代码中,setTimeout("setColor()", 500);
这行代码用于每隔500毫秒调用一次 setColor
函数。然而,由于你在 setColor
函数内部递归调用自身,这会导致函数调用栈变得非常深,从而影响性能。随着时间的推移,JavaScript 引擎可能无法准确地按照500毫秒的时间间隔执行定时器。
建议使用 setInterval
替代递归调用 setTimeout
,这样可以更好地控制时间间隔,并且避免递归调用带来的性能问题。
以下是修改后的代码示例:
<!DOCTYPE html>
<html>
<head>
<title>test</title>
<style type="text/css">
.main {
width: 600px;
height: 500px;
margin: 10px auto;
border: 1px solid #ccc;
}
.item {
width: 50px;
height: 20px;
line-height: 20px;
border: 1px solid #ccc;
float: left;
margin: 2px 2px;
}
</style>
<script type="text/javascript" src="jquery-1.4.2.min.js"></script>
<script type="text/javascript">
function GetColor() {
var str = "0123456789abcdef";
var t = "#";
for (var j = 0; j < 6; j++) {
t += str.charAt(Math.floor(Math.random() * str.length));
}
return t;
}
var arr = new Array();
var i = 0;
function setColor() {
var num = Math.floor(Math.random() * (100 - 1 + 1) + 1);
var t = 0;
if (arr.length == 100) {
$("div").css("background-color", "#ffffff");
i = 0;
arr = [];
}
if (i == 0) {
arr[i] = num;
i++;
} else {
for (var j = 0; j < arr.length; j++) {
if (num == arr[j]) {
t++;
}
}
if (t > 0) {
return;
} else {
arr[i] = num;
i++;
}
}
var id = "#d" + num;
var color = GetColor();
$(id).css("background-color", color);
}
setInterval(setColor, 500);
</script>
</head>
<body>
<div class="main">
<!-- 100个div -->
</div>
</body>
</html>
在这个版本中,我将递归调用 setTimeout
改为使用 setInterval
来定期调用 setColor
函数。这样可以确保每次调用之间保持一致的时间间隔,并且避免了递归调用带来的性能问题。