Skip to content

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('工作完成')

// 输出:
// 开始工作
// 工作完成
// 执行清理操作

注意事项

  1. 执行时机: 函数会在当前执行栈清空后执行,通常是在下一个事件循环中
  2. 参数传递: 延迟执行的函数会接收到调用时传递的所有参数
  3. 错误处理: 如果在延迟执行过程中发生错误,错误会被抛出到全局作用域
  4. 返回值: 延迟执行的函数如果有返回值,会被忽略
  5. 性能: 使用 setTimeout(fn, 0)setImmediate 实现

与其他方法的区别

  • setTimeout(fn, 0): 功能相同,但 defer 更简洁
  • setImmediate(): Node.js环境中的类似功能
  • queueMicrotask(): 在下一个微任务中执行,而不是宏任务
  • Promise.resolve().then(): 微任务,执行时机不同

实际应用场景

  1. 事件处理: 延迟处理用户交互事件
  2. 清理操作: 在函数返回前执行清理
  3. 日志记录: 延迟记录日志,避免阻塞主流程
  4. 状态更新: 延迟更新UI状态
  5. 错误处理: 延迟处理错误,确保主流程不受影响

Released under the MIT License.