为什么这个Javascript setTimeout和setInterval会遇到竞争条件?

时间:2017-03-09 16:40:33

标签: javascript carousel settimeout setinterval race-condition

document.addEventListener("DOMContentLoaded", function(event) {
	window.setInterval(rotateCarousel, 5000);
});

function fadeCarousel(n, e, t, s){
	var carousel = window.setInterval(function(){
		console.log(t/s);
			if (e.children[n].style.opacity>0){
				e.children[n].style.opacity = String(parseFloat(e.children[n].style.opacity) - .01);
			}
			
			if (e.children[(n+1) % e.childElementCount].style.opacity <1){
				e.children[(n+1) % e.childElementCount].style.opacity = String(parseFloat(e.children[(n+1) % e.childElementCount].style.opacity) + .01);
			}
	}, t/s);
	
	window.setTimeout(function(){
		clearInterval(carousel);
	},t);
};

function rotateCarousel(){
	var carouselinner = document.getElementsByClassName("carousel-inner")[0];
	var activeChild = 0;
	
	for (i=0; i< carouselinner.childElementCount; i++){
		if (carouselinner.children[i].classList.contains("active")){
			activeChild=i;
			i=carouselinner.childElementCount;
		}
	}
	
	fadeCarousel(activeChild, carouselinner, 500, 100);
	carouselinner.children[activeChild].classList.remove("active");
	carouselinner.children[(activeChild+1) % carouselinner.childElementCount].classList.add("active");
};
.carousel { 
  z-index: -100; 
} /* keeps this behind all content */

.carousel .item {
	top:0;
	left:0;
  position: fixed; 
  width: 100%; 
	height: 100%;
	background-position: center;
}

.carousel .one {
		background-color:green;
		background-size: cover;
	}
	.carousel .two {
		background-color:blue;
		background-size: cover;
	}
	.carousel .three {
		background-color:yellow;
		background-size: cover;
	}
	.carousel .four {
		background-color: red;
		background-size: cover;
	}
<div id="BackgroundCarousel" class="carousel container slide">
  <div class="carousel-inner">
    <div class="item one active" style="opacity: 1;"></div>
    <div class="item two" style="opacity: 0;"></div>
    <div class="item three" style="opacity: 0;"></div>
    <div class="item four" style="opacity: 0;"></div>
  </div>
</div>

以上是我遇到的一个例子。

我想要做的是让背景的透明度在设定的时间间隔内旋转和旋转,因此我使用setInterval来调用将rotateCarousel标记为div的函数fadeCarousel显示的div并调用转换。

在改变时,我希望有一个淡入淡出过渡,所以我有一个函数setInterval,可以在短时间内调整两个相邻背景div的不透明度。由于我希望div的淡化停止,因此我会清除setTimeout中的setInterval的淡出setInterval,其延迟应允许setTimeout中的所有内容完成。

似乎当我使用精确值来延迟清除时间间隔时浏览器没有足够的时间来完成clearInterval淡入淡出以及setInterval运行{{1有时淡入淡出的clearInterval不完整。这使我的背景看起来陷入过渡期。

我试图解决这个问题,因为console.log被调用需要大约5倍的延迟,但有时似乎仍有问题(没有大的余量,似乎有每次比赛条件)。我也有t/s打印t,因为在Firefox中似乎没有s&amp; setInterval会被优化掉,并且发生了奇怪的事情。

我不理解setTimeoutalter session set timed_statistics=ALL; <run your query> select * from table( dbms_xplan.display_cursor( null, null, 'ALLSTATS LAST ) ); - 为什么这里会出现竞争条件?

1 个答案:

答案 0 :(得分:1)

因为更改活动元素时for循环错误,所以间隔未完成。这就是为什么当下一个元素激活时你的间隔已经清除。和你的竞争条件。我已修复此代码,我尝试在清除前向元素间隔后调用set interval next元素。见代码剪切

var activeChild = -1;
document.addEventListener("DOMContentLoaded", function(event) {
	rotateCarousel();
});

function fadeCarousel(n, e, t, s){
	var carousel = window.setInterval(function(){
		  console.log(t/s);
			if (e.children[n].style.opacity>0){
				e.children[n].style.opacity = String(parseFloat(e.children[n].style.opacity) - .01);
			}
			
			if (e.children[(n+1) % e.childElementCount].style.opacity <1){
				e.children[(n+1) % e.childElementCount].style.opacity = String(parseFloat(e.children[(n+1) % e.childElementCount].style.opacity) + .01);
			}
	}, t/s);
	window.setTimeout(function(){
    console.log("clear");
		clearInterval(carousel);
    rotateCarousel();
	},t);	
};

function rotateCarousel(){
  activeChild+=1;
	var carouselinner = document.getElementsByClassName("carousel-inner")[0];
  if(carouselinner.childElementCount <= activeChild){
    activeChild = 0;
  }
   console.log("element: " + activeChild);	
  if(activeChild > 0){
     carouselinner.children[activeChild - 1].classList.remove("active");
  }
	carouselinner.children[activeChild].classList.add("active");
  fadeCarousel(activeChild, carouselinner, 3000, 1000);
  
};
.carousel { 
  z-index: -100; 
} /* keeps this behind all content */

.carousel .item {
	top:0;
	left:0;
  position: fixed; 
  width: 100%; 
	height: 100%;
	background-position: center;
}

.carousel .one {
		background-color:green;
		background-size: cover;
	}
	.carousel .two {
		background-color:blue;
		background-size: cover;
	}
	.carousel .three {
		background-color:yellow;
		background-size: cover;
	}
	.carousel .four {
		background-color: red;
		background-size: cover;
	}
<div id="BackgroundCarousel" class="carousel container slide">
  <div class="carousel-inner">
    <div class="item one" style="opacity: 1;"></div>
    <div class="item two active" style="opacity: 0;"></div>
    <div class="item three" style="opacity: 0;"></div>
    <div class="item four" style="opacity: 0;"></div>
  </div>
</div>

您的代码设置间隔调用 rotateCarousel(),当您的函数 fadeCarousel 被调用时, rotateCarousel 的间隔调用:) strong> fadeCarousel 比intervall insite fadeCarousel 更快地调用。 EX:

1:window.setInterval(rotateCarousel,5000); // A 表示5s后rotateCarousel将调用。

2:fadeCarousel(activeChild,carouselinner,500,100); // B 在500ms关闭后。

但是:当 A 进行下一次通话意味着在5s B 之前完成4.5s之前。想一想:在 A 之后拨打电话 B 已经完成5000 - (n * 500ms),为什么 activeChild 竞争条件(我正在努力)改善我的英语)如果你不明白请告诉我做一个例子。