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狀態
- 錯誤處理: 延遲處理錯誤,確保主流程不受影響