# 使用 Effect 提升前端應用程式的穩定性與可維護性 - 彭勝宇
{%hackmd @JSDC-tw/B1loEcwJZl %}
###### tags: `JSDC2025`
Slido:https://app.sli.do/event/pG5n1iyWYfa6TEpoLA7DA6
Effect 的官網: https://effect.website
講者寫的教學文章: https://ithelp.ithome.com.tw/users/20111802/ironman/8800
互動式的 Effect 教學: https://effect.kitlangton.com
簡報:
- [web 版](https://dansnow.github.io/talks/2025-11-29-jsdc/)
- [pdf 版](https://github.com/DanSnow/talks/blob/main/slides/2025-11-29-jsdc/%E4%BD%BF%E7%94%A8%20Effect%20%E6%8F%90%E5%8D%87%E5%89%8D%E7%AB%AF%E6%87%89%E7%94%A8%E7%A8%8B%E5%BC%8F%E7%9A%84%E7%A9%A9%E5%AE%9A%E6%80%A7%E8%88%87%E5%8F%AF%E7%B6%AD%E8%AD%B7%E6%80%A7%20-%20Slidev.pdf)
> 開始做筆記
Effect 很少人聽過,更不用說用過的人了
2020 出,2024 - 2025 12K Starts
講者在發哥 David Peng
https://github.com/danshow
## Type-Safe Error Handling
Demo Code 潛在的錯誤
```ts=
function getData(id: string) {
const r = await fetch(`/items/${id}`); // Fetch 網路問題
return r.json() // JSON 型別不明
}
```
嘗試 Handling, 程式碼大暴增,這裡只列部分 slide
```ts=
invariant(id.length > 0, 'id 長度');
throw new Error();
```
- 複雜度
### Effect Type
```ts=
// Original: Effect<A, E, R>
Effect<Success, Error, Requirements>
```
設置檢查點
上述範例改寫
```ts=
Effect.fn('fetchDetail')(function *(id: string) {
const res = yield* Effect.tryPromise({
try: () => fetch(`/items/${id}`);
catch: () => throw
})
});
```
> 重新發現 Generator 的好
async + await 放到 JS Runtime
generator 放到 code 的外面,丟出去然後從 yield 拿回來
```ts=
function *fetchDetail() {
const a = yield *getXXX();
}
Effect.run(
fetchDetail(),
(error) => handleError(error)
);
```
Promise 的短處:
1. 無法標示可能發生的錯誤
2. API 設計 -> 錯誤碼多,non 200 + network
### Schema 定義型態
```ts=
const ItemSchema = Schema.Struct({
id: Schema.String,
});
type ItemDetail = typeof ItemSchema.Type;
```
## Effect 畫藍圖
```ts=
pRetry(
async () => {
const result = await flaskyAPI();
},
{
retries: 3,
minTimeout: 500,
factor: 2
}
)
```
Effect
```ts=
Effect.tryPromise(
),
Effect.retry({
times: 3,
})
```
```ts=
Effect.all(
[
fetchUser(1),
],
{
concurrency: 'unbounded'
}
)
```
Q&A: 包起來,要怎麼平行地處理 yield? Effect runtime 也可以處理
> function programming 的延伸
強調 "要做什麼",自由組裝
### Dependencies Injection
`Effect.provideService`
### Demo
Trello
- 從[TypeSense](https://typesense.org/)不同抓取條件
- 一次抓多個
- 大量平行請求
- 網路不穩定處理
背後會幫你組合起來
案例分享:瀏覽器資料遷移
- 本機資料與 Server 資料會重複生成很多
- 累積了不少資料
- 決定一次將 Client 資料傳上 Server,資料量過大
`withProgressRecord` 追蹤資料走向
`Effect.addWith` 一次收集全部
## 導入 Effect 遇到的問題
- Learning Curve
- New Concepts to be used to
- Resolve:
- From small side project
- Code Review to share knowledge
- 擅長
- 複雜錯誤
- 異步
- Retry
- Concurrency
- 資源管理
- 依賴注入
- 類型安全
# Q & A
- 有互動教學:https://effect.kitlangton.com
午安,想知道 Effect 跟 RxJS 有什麼差異呢?
- RxJS 處理 Steam
前端資料容易被後端資料架構限制,要怎麼導入
- 先用熟悉的方式
佔空間?
- 看你怎麼使用
- 開發電商會有固定流程
- 若遇到複雜狀況可以考慮
vs fp-ts
- fp-ts 作者加入 Effect 了!
Effect 推薦使用 fp 嗎?class
- 的確鼓勵使用 fp,除了部分 class
> 聊天區
---
{%hackmd @JSDC-tw/jsdc2025_sponsor %}