
关于
使用 TaskEither 的实用异步模式——用清晰的管道替代 try/catch 地狱,附带真实 API 示例。
name: fp-async description: 使用 TaskEither 的实用异步模式——用干净的管道替代 try/catch 地狱,附带真实 API 示例 risk: unknown source: community version: 1.0.0 author: kadu tags:
- fp-ts
- typescript
- async
- error-handling
- practical
- promises
- api
- fetch
fp-ts 实用异步模式
停止编写嵌套的 try/catch 块。停止丢失错误上下文。开始构建正确处理错误的干净异步管道。
TaskEither 就是一个跟踪成功或失败的异步操作。 就这么简单。不需要花哨的术语。
何时使用
- 需要在 TypeScript 中使用
TaskEither进行异步错误处理时。 - 任务涉及包装 Promise、组合 API 调用或替换嵌套的
try/catch流程时。 - 需要实用的 fp-ts 异步模式而非学术解释时。
// TaskEither<Error, User> means:
// "An async operation that either fails with Error or succeeds with User"
1. 安全包装 Promise
问题:到处都是 Try/Catch
// BEFORE: Try/catch hell
async function getUserData(userId: string) {
try {
const response = await fetch(`/api/users/${userId}`)
if (!response.ok) {
throw new Error(`HTTP ${response.status}`)
}
const user = await response.json()
try {
const posts = await fetch(`/api/users/${userId}/posts`)
if (!posts.ok) {
throw new Error(`HTTP ${posts.status}`)
}
const postsData = await posts.json()
return { user, posts: postsData }
} catch (postsError) {
console.error('Failed to fetch posts:', postsError)
return { user, posts: [] }
}
} catch (error) {
// Lost all context about what failed
}
}
解决方案:TaskEither 管道
import { pipe } from 'fp-ts/function'
import * as TE from 'fp-ts/TaskEither'
const fetchUser = (userId: string): TE.TaskEither<Error, User> =>
TE.tryCatch(
() => fetch(`/api/users/${userId}`).then(r => r.json()),
(reason) => new Error(`Failed to fetch user: ${reason}`)
)
const fetchPosts = (userId: string): TE.TaskEither<Error, Post[]> =>
TE.tryCatch(
() => fetch(`/api/users/${userId}/posts`).then(r => r.json()),
(reason) => new Error(`Failed to fetch posts: ${reason}`)
)
兼容工具
Claude CodeCursor
标签
前端开发