defer
延迟执行一个函数,直到当前执行栈清空。
基础用法
typescript
import { defer } from 'radash'
const deferred = defer(() => {
console.log('这个会在当前执行栈清空后执行')
})
console.log('这个会先执行')
// 输出:
// 这个会先执行
// 这个会在当前执行栈清空后执行
语法
typescript
function defer<T extends (...args: any[]) => any>(
fn: T
): (...args: Parameters<T>) => void
参数
fn
(T): 要延迟执行的函数
返回值
返回一个函数,该函数会在当前执行栈清空后执行原始函数。
示例
基本延迟执行
typescript
import { defer } from 'radash'
const deferredFn = defer(() => {
console.log('延迟执行')
})
console.log('立即执行')
deferredFn()
console.log('同步执行')
// 输出:
// 立即执行
// 同步执行
// 延迟执行
传递参数
typescript
import { defer } from 'radash'
const deferredSum = defer((a: number, b: number) => {
console.log(`延迟计算: ${a} + ${b} = ${a + b}`)
})
deferredSum(5, 3)
console.log('这个会先执行')
// 输出:
// 这个会先执行
// 延迟计算: 5 + 3 = 8
处理异步操作
typescript
import { defer } from 'radash'
const deferredAsync = defer(async () => {
console.log('开始异步操作')
await new Promise(resolve => setTimeout(resolve, 100))
console.log('异步操作完成')
})
deferredAsync()
console.log('同步代码执行')
// 输出:
// 同步代码执行
// 开始异步操作
// 异步操作完成
在事件处理中使用
typescript
import { defer } from 'radash'
const handleClick = defer(() => {
console.log('按钮被点击了')
})
// 模拟按钮点击
console.log('准备点击')
handleClick()
console.log('点击事件已触发')
// 输出:
// 准备点击
// 点击事件已触发
// 按钮被点击了
处理错误
typescript
import { defer } from 'radash'
const deferredError = defer(() => {
throw new Error('延迟执行的错误')
})
try {
deferredError()
console.log('这行会执行')
} catch (error) {
console.log('错误被捕获:', error.message)
}
// 输出:
// 这行会执行
// 错误被捕获: 延迟执行的错误
与Promise结合
typescript
import { defer } from 'radash'
const deferredPromise = defer(() => {
return Promise.resolve('延迟的Promise结果')
})
console.log('开始执行')
deferredPromise().then(result => {
console.log('Promise结果:', result)
})
console.log('同步代码结束')
// 输出:
// 开始执行
// 同步代码结束
// Promise结果: 延迟的Promise结果
清理操作
typescript
import { defer } from 'radash'
const cleanup = defer(() => {
console.log('执行清理操作')
})
console.log('开始工作')
// ... 一些工作 ...
cleanup()
console.log('工作完成')
// 输出:
// 开始工作
// 工作完成
// 执行清理操作
注意事项
- 执行时机: 函数会在当前执行栈清空后执行,通常是在下一个事件循环中
- 参数传递: 延迟执行的函数会接收到调用时传递的所有参数
- 错误处理: 如果在延迟执行过程中发生错误,错误会被抛出到全局作用域
- 返回值: 延迟执行的函数如果有返回值,会被忽略
- 性能: 使用
setTimeout(fn, 0)
或setImmediate
实现
与其他方法的区别
setTimeout(fn, 0)
: 功能相同,但defer
更简洁setImmediate()
: Node.js环境中的类似功能queueMicrotask()
: 在下一个微任务中执行,而不是宏任务Promise.resolve().then()
: 微任务,执行时机不同
实际应用场景
- 事件处理: 延迟处理用户交互事件
- 清理操作: 在函数返回前执行清理
- 日志记录: 延迟记录日志,避免阻塞主流程
- 状态更新: 延迟更新UI状态
- 错误处理: 延迟处理错误,确保主流程不受影响