首页 > 解决方案 > 理解 setTimeout

问题描述

我一直试图让一系列句子在前一个句子之后 2 秒出现,使用 setTimeout 显示每个句子,并使用 setInterval 重复这个过程一定次数(由用户定义)。

以下示例代码显示了我的理解和困惑:

	var myComments = document.getElementById("comments");
	var subtractor = 5;
	var timer, myRun;
	
	window.onload = onStart();
	
	function onStart() {
		alert("First Comment");
		myRun = setInterval(function() {
			alert("Sub = " + subtractor);
			setTimer("<p>This is a first sentence. Subtractor = " + subtractor + "</p>");
			setTimer("<p>This is a second sentence. Subtractor = " + subtractor + "</p>");
			setTimer("<p>This is a third sentence. Subtractor = " + subtractor + "</p>");
			subtractor = subtractor - 1;
			if (subtractor < 1) {
				alert("Subtractor to clear");
				clearInterval(myRun);
				}
		}, 2000);
		alert("Last Comment");
	}
	
	function setTimer(setText) {
		clearTimeout(timer);
		timer = setTimeout(function() {myComments.innerHTML = myComments.innerHTML + setText;}, 2000);
	}
<div id="comments"></div>

警报只是作为测试点存在,表明我缺乏理解:

抱歉,最后一个问题更多的是我自己的想法;去测试!

标签: javascript

解决方案


为什么在第一个警报之后立即显示最后一个警报,然后在 setInterval 内显示警报?

最后一个警报不在 setTimeout 或 setInterval 内,因此会立即触发。其他的都在 2000 毫秒的 setTimeout 内,所以两秒钟后触发(一次全部)。

为什么除了生成的最后一句话外,没有任何句子显示?

您正在以相同的 2000 毫秒延迟同时触发三个 setTimeouts,因此两秒后它们几乎同时触发三个。它们内部的 clearTimeouts 相互冲突(因为您重复使用相同的timer变量来跟踪它们),这阻止了它们中的两个被触发。

我哪里错了?

您对 setTimer 的每个调用都应该使用不同的时间延迟,这样它们就不会一次全部触发。同时,setInterval 应该有足够长的间隔,这样它就不会在它设置的三个 setTimeouts 完成之前循环。无需在 setTimout 调用上调用 clearTimeout;默认情况下,它们会运行一次然后停止,这就是您想要的。您唯一需要的地方就是停止 setInterval。

您可能还想立即触发第一次迭代,因此它会立即开始,而不是等待第一个间隔完成:

var myComments = document.getElementById("comments");
var subtractor = 5;
var timer, myRun;

window.onload = onStart();

function setTimers() {
  //alert("Sub = " + subtractor);
  setTimer("<p>This is a first sentence. Subtractor = " + subtractor + "</p>", 0); // no delay
  setTimer("<p>This is a second sentence. Subtractor = " + subtractor + "</p>", 2000); // 2s delay
  setTimer("<p>This is a third sentence. Subtractor = " + subtractor + "</p>", 4000); // 4s delay
  subtractor = subtractor - 1;
  if (subtractor < 1) {
    //alert("Subtractor to clear");
    clearInterval(myRun);
  }
}

function onStart() {
  //alert("First Comment");
  myRun = setInterval(setTimers, 6000); // 6 seconds for the full interval
  setTimers(); // so you don't have to wait 6 seconds for the first run
}

function setTimer(setText, delay) {
  timer = setTimeout(function() {
    myComments.innerHTML = myComments.innerHTML + setText;
  }, delay);
}
<div id="comments"></div>


推荐阅读