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.