2025-02-19-Callback Hell(回呼地獄)

2025-02-19-Callback Hell(回呼地獄)

你現在理解「什麼是 callback」的概念已經沒問題,接下來我們來說「無限 callback」這個說法,其實它通常不是指「真的無限次數」,而是指:


🔁 過度巢狀、層層相依的 callback 函式結構

這種情況被稱為:

Callback Hell(回呼地獄)
中文常說「巢狀過深的 callback」,程式碼會一層包一層,很難閱讀與維護。


📦 範例:層層相依的 callback(模擬查天氣 → 查空氣 → 查穿搭建議)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
function getWeather(callback) {
setTimeout(() => {
console.log('☁️ 查到天氣:陰天')
callback('陰天')
}, 1000)
}

function getAirQuality(weather, callback) {
setTimeout(() => {
console.log('🌫️ 查到空氣品質:普通')
callback(weather, '普通')
}, 1000)
}

function getSuggestion(weather, airQuality, callback) {
setTimeout(() => {
console.log('👕 根據天氣和空氣品質,建議穿薄外套')
callback()
}, 1000)
}

// 🧨 callback 一層又一層
getWeather((weather) => {
getAirQuality(weather, (weather, airQuality) => {
getSuggestion(weather, airQuality, () => {
console.log('✅ 所有資料都查完了')
})
})
})

😵 問題在哪?

這樣的寫法問題是:

  • 每加一個功能就要多縮排一層(維護困難)
  • 越來越亂,看不出邏輯結構
  • 錯誤處理變得非常複雜(哪裡出錯都不好找)

✅ 解法:用 Promiseasync/await 改寫

這就是為什麼現代 JS 推薦用 Promiseasync/await,你只要寫成這樣:

1
2
3
4
5
6
7
async function main() {
const weather = await getWeatherAsync()
const air = await getAirQualityAsync(weather)
await getSuggestionAsync(weather, air)
console.log('✅ 所有資料都查完了')
}
main()

是不是整齊超多?😊


總結:你問的「無限 callback」是什麼?

➡️ 其實是指 callback 一層套一層、層層相依、難以閱讀的地獄式寫法,俗稱 callback hell,不是「真的無限次數」。