我一直试图让一系列句子出现在前一个句子后2秒,使用setTimeout显示每个句子,并使用setInterval重复此过程一定次数(由用户定义)。 / p>
以下示例代码显示了我的理解位置以及我感到困惑的地方:
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);
}
&#13;
<div id="comments"></div>
&#13;
警报只是作为测试点,并显示我缺乏理解:
对不起,最后一个问题更多是我自己的想法;试试!
答案 0 :(得分:1)
为什么在第一个警报之后立即显示最后一个警报,然后在setInterval内显示警报?
最后一个警报不在setTimeout或setInterval内,因此立即触发。其他人都在2000ms的setTimeout内,所以两秒钟之后就会开火(一次全部开火)。
除了生成的最后一句话之外,为什么没有显示任何句子?
你以相同的2000毫秒延迟同时发射三个setTimeouts,因此所有三个都在两秒钟之后几乎同时发射。它们内部的clearTimeout相互碰撞(因为你重复使用相同的timer
变量来跟踪它们),这阻止了它们中的两个被激活。
我哪里错了?
您对setTimer的每次调用都应使用不同的时间延迟,这样他们就不会同时触发所有内容。同时,setInterval应该具有足够长的间隔,因此在它设置的三个setTimeout完成之前它不会循环。无需在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);
}
&#13;
<div id="comments"></div>
&#13;
答案 1 :(得分:0)
看到另一个答案解释了问题,我只会回答“我将如何实现我想要的”评论 - 从最现代(和最干净的代码)方式开始
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>
我不会理解用“不断增加的超时值”做你想要的最简单的方法,因为已经显示了