【问题标题】:Can you update setInterval variable while it runs您可以在运行时更新 setInterval 变量吗
【发布时间】:2021-04-26 21:47:26
【问题描述】:
我需要修改现有的滑块。它的幻灯片现在添加了不同的数据秒数,并且需要长时间处于活动状态。以前我有:
var slidePause = 10;
function startSlideBanner() {
bannerTimer = setInterval(nextSlide, slidePause * 1000);
}
startSlideBanner();
效果非常好。现在我需要在每次迭代时更新 slidePause 变量。如果可能的话,寻找一个例子。
【问题讨论】:
标签:
javascript
settimeout
setinterval
【解决方案1】:
不:你不能用setInterval 来做。一旦设置,只能取消。
但是,您可以使用setTimeout 来实现您的目标。虽然这可以递归地完成,但我更喜欢利用 promises 来迭代地完成它:
const wait = ms => new Promise(res => setTimeout(res, ms));
let slidePause = 10;
async function startSlideBanner() {
while(true) {
await wait(slidePause * 1000);
nextSlide();
// Example: Double the time for each slide
slidePause = slidePause * 2;
}
}
startSlideBanner();
【解决方案2】:
setInterval() 的一个问题是 JavaScript 的单线程特性会导致 setInterval() 代码被触发之间的不均匀周期。为避免这种情况,请以更快的速度运行setInterval(),并计算经过的时间以确定是否应采取行动。
如果您根据变量计算经过的时间,则可以更改事件发生的有效速率。
function nextSlide(period){
console.log("Next Slide in "+period);
}
function VariableTimer(period, startImmediately = true) {
this.period = period;
self = this;
this.startTime = startImmediately?0:Date.now();
this.time = setInterval(function(){
if (Date.now()-self.startTime > self.period*1000) {
self.startTime = Date.now();
nextSlide(self.period);
}
}, 100); // Run setInterval at 100ms intervals.
this.stop = function(){
clearInterval(self.time);
}
}
let timer = new VariableTimer(10);
// Change the timer period like this
// timer.period = 5;
// After 20 seconds switch to 5 second intervals
setTimeout(function(){timer.period = 5;},20000);
// After 40 seconds, stop the timer.
setTimeout(function(){timer.stop();console.log("timer stopped")}, 40000);