setTimeout()、setInterval()不起作用?答案在这里

本文揭示了在JavaScript中使用setTimeout()时容易出现的困惑,包括延迟调用函数的理解、setInterval()的误用及参数设置不当等问题,并提供了具体的解决策略,帮助开发者避免常见错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有小伙伴在使用setTimeout()中会有疑惑,为什么我设置的延迟不起作用?
给你揭晓答案

首先,setTimeout()的定义和用法是:

setTimeout() 方法用于在指定的毫秒数后调用函数或计算表达式。

画重点:是调用 函数!!或计算表达式!。

所以正确的写法是写在function之中,不能直接写语句;

setTimeout(function(){ alert(1); },200);

有时候还是会忽略,再来温馨提示一下:

setInterval(myScroll("#demo"), 5000);

该语句实际执行多少次,慧眼的小伙伴看出问题了吗?

正确答案:

仅执行一次!!!

第一个参数要为:执行的函数!

我写的是一个函数的执行myScroll("#demo"), 因为后面加了(),所以是一个执行,而不是个函数

修改办法:将函数执行变为匿名函数

setInterval(function(){myScroll("#demo")}, 5000);

这是关于第一个参数尤其需要注意的地方。另外不起作用的情况就是this的指向问题了,要有意识的注意一下。

在开发过程中还会遇到滚动越来越快的情况,这个时候需要用clearInterval()来清除一下。

let time = setInterval(function(){self.AutoScroll("#demo")}, 5000);

clearInterval(time)

转载于:https://juejin.im/post/5b4c346e5188251abf414ede

<think>嗯,用户问如何用setTimeout实现setInterval的效果。首先,我需要回忆一下这两个函数的区别。setInterval会按照指定的时间间隔重复执行函数,而setTimeout只会执行一次。但有时候setInterval可能会有问题,比如如果回调执行时间比间隔长,就会导致多个回调堆积。所以用setTimeout模拟可能更可控。 那具体怎么做呢?应该是在每次setTimeout的回调中再次调用setTimeout,形成一个循环。比如,定义一个函数,里面执行目标函数,然后设置一个新的setTimeout来调用自身。这样就能实现间隔执行的效果。 然后,用户可能还需要停止这个循环,所以应该返回一个清除的函数,或者类似clearInterval的机制。比如,在每次设置setTimeout的时候,保存返回的timer ID,然后提供一个方法来清除它。 举个例子,写一个函数mySetInterval,接受回调函数和间隔时间。在内部定义一个wrapper函数,里面执行回调,然后设置setTimeout调用wrapper,同时保存新的timer ID。这样每次都是在上一次回调结束后才设置下一次,避免了间隔重叠的问题。 还要考虑如何停止这个循环。可以返回一个对象,里面有一个clear方法,用来清除当前的timer。或者在每次设置timer时更新一个变量,这样clear的时候可以取消最新的timer。 另外,可能需要处理错误,确保即使回调抛出异常,后续的定时器仍然能够继续。不过通常可能不需要,因为用户希望出错时停止?或者应该用try-catch包裹回调? 再想想,用户可能想要的是准确的间隔,还是每次回调执行完毕后再等间隔时间。用setTimeout模拟的话,是后者,即间隔是从回调结束开始计算的。而setInterval是固定间隔,不管回调执行时间。这点需要说明清楚。 然后,代码示例。比如: function mySetInterval(callback, interval) { let timerId; function repeat() { callback(); timerId = setTimeout(repeat, interval); } timerId = setTimeout(repeat, interval); return { clear: () => clearTimeout(timerId) }; } 这样每次执行完callback后,再设置下一次的setTimeout。然后返回一个clear方法,可以清除当前的定时器。 然后,用户可能还需要处理参数传递,比如如果回调需要参数的话。这时可以在repeat函数里调用callback.apply或者用箭头函数传参。 另外,可能需要处理首次执行是否需要立即执行。比如setInterval是在间隔后第一次执行,而用setTimeout模拟也是同样的行为。如果用户想要立即执行,可以调整代码,先调用一次callback,再设置定时器。 但原题是模拟setInterval,所以应该保持行为一致,即首次执行在间隔之后。 总结步骤: 1. 使用递归的setTimeout调用。 2. 每次执行回调后设置下一次的定时器。 3. 提供清除定时器的方法。 4. 处理可能的参数传递和错误情况。 然后解释为什么这样做更好,比如避免了setInterval可能出现的回调堆积问题,因为下一次的执行总是在前一次完成之后才被安排。 相关问题可能涉及setTimeoutsetInterval的区别,递归setTimeout的优缺点,如何清除定时器,或者如何处理异步回调的情况。</think><< 可以通过递归调用 `setTimeout` 来模拟 `setInterval` 的效果。以下是实现方法: ```javascript function customInterval(callback, interval) { let timerId = null; function repeat() { callback(); timerId = setTimeout(repeat, interval); // 递归调用 } timerId = setTimeout(repeat, interval); // 首次启动 return { // 返回清除方法 clear: () => clearTimeout(timerId) }; } // 使用示例 const interval = customInterval(() => { console.log("执行"); }, 1000); // 5秒后停止 setTimeout(() => interval.clear(), 5000); ``` **实现原理**: 1. **递归调用**:每次 `setTimeout` 执行完毕后,再次调用自身形成循环。 2. **避免重叠**:与原生 `setInterval` 不同,这种方式能确保前一次回调完成后再启动下一次计时。 3. **控制停止**:通过返回的 `clear()` 方法清除定时器。 **原生 setInterval 的缺陷**: - 如果回调执行时间超过间隔时间,会导致多个回调堆积。 - 无法动态调整下一次调用的间隔时间。 **递归 setTimeout 的优势**: - 每次间隔从前一次回调结束时开始计算。 - 更灵活控制执行流程(如动态调整间隔)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值