Cordis定时器服务全解析:timeout、interval、throttle与debounce一次学会
【免费下载链接】cordisMeta-Framework of Spatiotemporal Composability项目地址: https://gitcode.com/GitHub_Trending/co/cordis
Cordis 是一款基于「时空组合性」理念的元框架(Meta-Framework),其内置的Cordis定时器服务为开发者提供了timeout、interval、throttle、debounce四个开箱即用的定时器 API,并自动绑定上下文生命周期,无需手动清理。本文将从零开始,带你一次学会 Cordis 定时器服务的全部用法,掌握这四种定时器的核心区别与最佳实践,让定时任务开发更简单、更安全。
什么是Cordis定时器服务?
在 Cordis 中,定时器不是一个简单的工具函数,而是一个标准服务(Service),源码位于 packages/timer/src/index.ts。它通过ctx.mixin把能力直接挂载到 Context 上,安装后你就能直接调用:
ctx.timeout()一次性定时ctx.interval()循环定时ctx.throttle()节流ctx.debounce()防抖
其核心亮点在于:所有定时器都绑定当前 Context 的生命周期。当 Context 被销毁时,未触发的定时器会自动清除,从根本上杜绝了「定时器泄漏」这类经典问题。
快速上手:如何安装并启用定时器服务
定时器属于独立插件包,安装后通过ctx.plugin()注册即可:
import { Context } from 'cordis' import * as Timer from '@cordisjs/plugin-timer' const ctx = new Context() ctx.plugin(Timer)注册完成后,ctx.timeout、ctx.interval等方法即刻可用。核心注册逻辑可查看 packages/timer/src/index.ts 中的TimerService构造函数。
timeout:一次性定时器的三种用法
ctx.timeout()是最常用的定时器,支持三种调用方式:
1. 基础回调用法(返回清理函数)
const dispose = ctx.timeout(() => { console.log('3秒后执行一次') }, 3000)2. 手动取消
timeout返回的函数就是「取消开关」,调用后定时器立即失效:
const dispose = ctx.timeout(callback, 3000) dispose() // 提前取消,callback 不会执行3. Promise 写法(适合 async/await)
不传回调、只传延时,会返回一个 Promise,让定时器可以优雅地嵌入异步流程:
await ctx.timeout(3000) // 等待3秒 console.log('继续执行')🎯 补充小知识:ctx.setTimeout/ctx.setInterval是旧版 API,已被标记为 deprecated,新项目请直接使用ctx.timeout与ctx.interval。
interval:循环定时器的正确打开方式
ctx.interval()用于循环任务,同样有回调与 Promise 两种形态。
1. 回调用法:每秒执行一次
const dispose = ctx.interval(() => { console.log('每秒执行一次') }, 1000)2. 异步迭代器用法:可优雅退出
不传回调时,ctx.interval()返回一个异步迭代器,非常适合「按固定节奏处理数据」的场景:
for await (const _ of ctx.interval(1000)) { // 每秒执行一次 if (shouldStop) break // 直接 break 即可停止 }当 Context 被销毁时,迭代器会自动抛出错误终止,不会出现悬挂的循环任务。
throttle:节流函数的快速配置方法
ctx.throttle(callback, delay)让回调在指定时间内最多执行一次,适用于滚动、拖拽、按钮防连点等高频事件。
const throttled = ctx.throttle(save, 1000) window.addEventListener('scroll', throttled)- 连续触发时,第一个调用立即执行,后续调用被忽略;
- 第三个参数
noTrailing为true时,停止触发后不再补执行末尾一次(默认会补执行); - 返回的函数自带
.dispose(),调用后节流失效。
debounce:防抖函数的实用技巧
ctx.debounce(callback, delay)则是「停下来才执行」:持续触发会不断重置计时器,直到停止触发delay毫秒后才真正执行一次。
const debounced = ctx.debounce(search, 500) input.addEventListener('input', debounced)典型场景包括搜索联想、窗口 resize、表单校验——输入停顿 500ms 后再发起请求,避免高频网络调用。返回的函数同样支持.dispose()。
throttle与debounce的区别与选型指南
两者的区别可以浓缩成一句话:节流是「控制频率」,防抖是「等待静止」。
| 对比项 | throttle 节流 | debounce 防抖 |
|---|---|---|
| 执行时机 | 周期内最多一次 | 停止触发后执行一次 |
| 典型场景 | 滚动加载、拖拽 | 搜索联想、窗口缩放 |
| 高频触发时 | 定时执行,保证响应 | 合并为一次,节省资源 |
| 适用请求 | 需要持续反馈 | 只需最终结果 |
选型建议:需要持续反馈(如滚动加载图片)选throttle;只需最终结果(如输入搜索)选debounce。
生命周期管理:自动清理与手动释放
这是 Cordis 定时器服务最值得称赞的设计:每个定时器都通过ctx.effect()注册(相关实现见 packages/core/src/fiber.ts),当 Context 被销毁时,所有关联定时器自动清理。
因此你只需记住两条规则:
- 插件内部创建的定时器,无需手动清理,Context 销毁时自动释放;
- 需要提前终止的场景,调用返回值(
dispose()或.dispose())即可。
再配合 packages/timer/tests/index.spec.ts 中的完整测试用例,你可以轻松验证各 API 的边界行为,比如「销毁后不再触发」「break 后迭代器正常结束」等。
总结:四个 API 一次学会
| API | 作用 | 返回值 | 是否自动清理 |
|---|---|---|---|
ctx.timeout() | 延时执行一次 | 取消函数 / Promise | ✅ |
ctx.interval() | 定时循环执行 | 取消函数 / 异步迭代器 | ✅ |
ctx.throttle() | 频率控制 | 带.dispose的函数 | ✅ |
ctx.debounce() | 停止后执行 | 带.dispose的函数 | ✅ |
掌握 Cordis 定时器服务的这四大金刚,你就能在处理延时任务、轮询、高频事件时游刃有余,同时享受框架带来的生命周期安全保障。赶紧动手试试吧!
【免费下载链接】cordisMeta-Framework of Spatiotemporal Composability项目地址: https://gitcode.com/GitHub_Trending/co/cordis
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考