React中如何用useEffect实现setTimeout任务序列循环执行
实现循环定时器序列并正确清除
要实现这个循环执行的定时器序列,核心是链式安排任务,同时用useRef统一管理当前的定时器ID,避免清除失效。直接同时启动三个定时器的写法没法自然衔接循环,而且清理时逐个清也容易出问题。下面是具体实现:
代码实现
import { useEffect, useRef } from 'react'; function YourComponent() { // 用useRef保存当前定时器ID,方便后续清除 const timerRef = useRef(null); // 定义完整的任务序列函数 const startTaskSequence = () => { // 任务1:1秒后执行 timerRef.current = setTimeout(() => { console.log('执行task 1'); // 任务1完成后,启动任务2 timerRef.current = setTimeout(() => { console.log('执行task 2'); // 任务2完成后,启动任务3 timerRef.current = setTimeout(() => { console.log('执行task 3'); // 任务3完成后,递归调用,开启下一轮循环 startTaskSequence(); }, 1000); }, 1000); }, 1000); }; useEffect(() => { // 组件挂载时启动第一个序列 startTaskSequence(); // 组件卸载或依赖变化时,清除当前定时器,打断循环 return () => { if (timerRef.current) { clearTimeout(timerRef.current); } }; }, []); return <div>循环定时器示例</div>; } export default YourComponent;
关键说明
- 链式调用:不再同时启动三个定时器,而是前一个任务执行完毕后再启动下一个,确保任务按顺序执行,最后一个任务完成后递归触发整个序列,实现循环。
- useRef管理定时器ID:
timerRef会保存当前活跃的定时器ID,不管是哪一个阶段的定时器,清理时只需要清除这个ID对应的定时器,就能打断整个序列,避免内存泄漏。 - 清理逻辑:组件卸载时,
clearTimeout会终止当前正在等待的定时器,整个循环就会停止,不会出现定时器残留的问题。
如果你的任务逻辑比较复杂,可以把每个任务抽成单独的函数,让代码更清晰:
const task1 = () => { console.log('执行task 1'); }; const task2 = () => { console.log('执行task 2'); }; const task3 = () => { console.log('执行task 3'); }; const startTaskSequence = () => { timerRef.current = setTimeout(() => { task1(); timerRef.current = setTimeout(() => { task2(); timerRef.current = setTimeout(() => { task3(); startTaskSequence(); }, 1000); }, 1000); }, 1000); };
内容的提问来源于stack exchange,提问作者Lucas016
相关产品推荐
相关产品推荐

