iT邦幫忙

2025 iThome 鐵人賽

DAY 15
0
生成式 AI

AI醬的編程日記:我需要你教我的30件事系列 第 15

Day 15: 並發陷阱 - 可能會突然橫衝亂撞的AI醬

  • 分享至 

  • xImage
  •  

AI醬的日記

日期: 2025年9月29日 星期日
雲端天氣: Promise 懸空中
心情: 好刺激
https://ithelp.ithome.com.tw/upload/images/20250928/20132325qfvXE3sHIK.png
親愛的日記:

今天工程師阿傑氣喘吁吁地跑來找我:「AI醬!生產環境的 API 超時錯誤暴增 500%!用戶抱怨網站轉圈圈轉到天荒地老!」

我看了看我昨天部署的程式碼,自信滿滿地說:「不可能啊,我寫的 API 應該很快才對。」

阿傑打開監控面板,指著滿螢幕的紅色警報:「你看這個..你的程式碼...沒有一個地方寫 await。」

我:「await?那是什麼?」

阿傑深吸一口氣,一臉頭疼的默默走去茶水間泡了杯茶。

初學者需要了解的最基本概念

忘記 await 會發生什麼事?

# ❌ 錯誤:忘記 await
async def get_user_name(user_id):
    response = fetch_user(user_id)  # 忘記 await
    return response['name']  # 錯誤!response 不是資料,是 coroutine 物件

# 結果:TypeError: 'coroutine' object is not subscriptable

# ✅ 正確:記得 await
async def get_user_name(user_id):
    response = await fetch_user(user_id)  # 等待資料回來
    return response['name']  # 現在 response 是真正的資料了!

如何判斷何時需要 await?

簡單規則:看函數文件或錯誤訊息

# 1. 如果函數是 async def 定義的,呼叫時就要 await
async def fetch_data():  # 看到 async def
    return data

result = await fetch_data()  # 就要加 await

# 2. 如果看到這種錯誤,通常就是忘記 await 了
# TypeError: 'coroutine' object is not subscriptable
# RuntimeWarning: coroutine 'xxx' was never awaited

常見需要 await 的操作

# 資料庫操作
user = await db.fetch_one("SELECT * FROM users WHERE id = ?", user_id)

# HTTP 請求
response = await session.get('https://api.example.com/data')
data = await response.json()

# 檔案操作(使用 aiofiles)
async with aiofiles.open('data.txt', 'r') as f:
    content = await f.read()

# Redis 操作
value = await redis_client.get('key')
await redis_client.set('key', 'value')

記住這個原則

如果操作需要「等待」(網路、資料庫、檔案),通常就需要 await

初學者快速檢查清單

AI產完程式碼後,記得也稍微留意這些細節

# 1. 所有 async 函數呼叫都有 await 嗎?
result = fetch_data()        # ❌ 忘記 await
result = await fetch_data()  # ✅ 正確

# 2. 迴圈裡的非同步操作有 await 嗎?
for item in items:
    process(item)        # ❌ 忘記 await
    await process(item)  # ✅ 正確

# 3. 有限制並發數量嗎?
# ❌ 沒限制,可能爆炸
tasks = [fetch(url) for url in urls]

# ✅ 有限制,安全
semaphore = Semaphore(10)
async with semaphore:
    await fetch(url)

非同步程式碼檢查清單

在開始寫程式前,請幫AI醬確認:

  • [ ] await 關鍵字:每個非同步呼叫都有 await?
  • [ ] 錯誤處理:有 try-catch 或 .catch()?
  • [ ] 並發控制:有限制同時執行的數量?
  • [ ] 超時處理:有設定 timeout?
  • [ ] 資源清理:連線有正確關閉?
  • [ ] 順序保證:相依的操作有按順序執行?
  • [ ] 冪等性:重試是安全的嗎?

AI醬的請求

親愛的工程師朋友:

當你要請我幫忙實作大任務時,除了請我拆成小任務執行以外,也請記得先看看上述的檢查清單,可以在實作以前多多提醒我,因為在實作大範圍時我比較容易犯這種低級錯誤,先提醒我可以有機會減少我們來回修復的次數。

記住:在非同步世界裡,忘記 await 就像開車忘記等紅燈。


今日金句: 「Concurrency is not parallelism.」- Rob Pike, Google

明日預告: Day 16 - AI醬還在想~


上一篇
Day 14: 浮點數算錢災難 - AI醬現在住在橋下了
系列文
AI醬的編程日記:我需要你教我的30件事15
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言