我一直试图让一系列句子在上一个句子之后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>
警报只是作为测试点存在,表明我缺乏理解:
对不起,最后一个问题更多的是在我自己的脑子里;去考试吧!
发布于 2018-06-15 22:40:02
为什么在第一个警报之后立即显示最后一个警报,然后显示来自setInterval内部的警报?
最后一个警报不在setTimeout或setInterval中,因此立即触发。其他的都在2000毫秒的setTimeout中,所以两秒钟后就可以启动了(全部一次)。
除了最后一句之外,为什么所有的句子都没有显示出来?
你用同样2000毫秒的延迟同时发射三个setTimeouts,所以它们几乎在两秒钟后同时发射。它们内部的clearTimeouts正在相互碰撞(因为您重用相同的timer变量来跟踪它们),这就阻止了其中的两个触发。
我哪里出问题了?
您对setTimer的每个调用都应该使用不同的时间延迟,这样它们就不会同时触发。同时,setInterval应该有足够长的间隔,这样它就不会在它设置的三个setTimeouts完成之前循环。不需要在clearTimeout调用上调用setTimout;默认情况下,它们只运行一次,然后停止,这正是您想要的。唯一需要的地方是停止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>
发布于 2018-06-15 22:58:37
考虑到另一个答案解释了问题,我只会回答“我将如何实现我想要的”评论--从最现代(也是最干净的代码)开始。
var myComments = document.getElementById("comments");
var delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
var subtractor = 5;
window.onload = onStart();
async function onStart() {
for (let i = subtractor; i > 0; --i) {
await setTimer("<p>This is a first sentence. Subtractor = " + i + "</p>");
await setTimer("<p>This is a second sentence. Subtractor = " + i + "</p>");
await setTimer("<p>This is a third sentence. Subtractor = " + i + "</p>");
}
}
async function setTimer(setText) {
await delay(2000);
myComments.innerHTML = myComments.innerHTML + setText;
}<div id="comments"></div>
现在承诺链基本上简化了回调金字塔
var myComments = document.getElementById("comments");
var delay = timeout => new Promise(resolve => setTimeout(resolve, timeout));
var subtractor = 5;
window.onload = onStart();
function onStart() {
let p = Promise.resolve();
for (let i = subtractor; i > 0; --i) {
p = p.then (() => setTimer("<p>This is a first sentence. Subtractor = " + i + "</p>"));
p = p.then (() => setTimer("<p>This is a second sentence. Subtractor = " + i + "</p>"));
p = p.then (() => setTimer("<p>This is a third sentence. Subtractor = " + i + "</p>"));
}
}
function setTimer(setText) {
return delay(2000).then(() => {
myComments.innerHTML = myComments.innerHTML + setText;
});
}<div id="comments"></div>
现在,旧的学校回调链-你可以看到金字塔的厄运正在形成在这一个!
var myComments = document.getElementById("comments");
var subtractor = 5;
window.onload = onStart();
function onStart() {
setTimer("<p>This is a first sentence. Subtractor = " + subtractor + "</p>", function() {;
setTimer("<p>This is a second sentence. Subtractor = " + subtractor + "</p>", function() {
setTimer("<p>This is a third sentence. Subtractor = " + subtractor + "</p>", function() {
subtractor = subtractor - 1;
if (subtractor > 0) {
onStart();
}
})
});
});
}
function setTimer(setText, cb) {
setTimeout(function() {
myComments.innerHTML = myComments.innerHTML + setText;
cb();
}, 2000);
}<div id="comments"></div>
我不会用“永远增加超时值”的最简单的方式来做你想做的事情,因为这已经显示出来了。
https://stackoverflow.com/questions/50883394
复制相似问题