首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >使用 Effect 魔法解锁 TypeScript 的函数式超能力!

使用 Effect 魔法解锁 TypeScript 的函数式超能力!

作者头像
萌萌哒草头将军
发布2025-05-12 10:55:50
发布2025-05-12 10:55:50
20300
代码可运行
举报
文章被收录于专栏:前端框架前端框架
运行总次数:0
代码可运行

前言

这个周末学习了一个新工具 Effect-TS ,打开我了写代码的新思路,现在迫不及待的分享给大家!

正文

Effect-TS 的核心是一个名为 Effect 的数据结构,它封装了副作用(例如网络请求、文件操作等),并提供了类型安全的操作方式。Effect 的几个关键特性包括:

  • 🔒 类型安全:通过 TypeScript 的类型推断,确保副作用的输入输出和错误类型明确!
  • 💻 流式(functional)编程风格:将多个操作符或函数按顺序组合起来,使代码更简洁、可读,并且符合函数式编程的理念。
  • 🚀 组合性:Effect 提供了丰富的组合操作符,类似 Lego 积木,让复杂逻辑变得简单。
  • 结构化并发:支持异步任务的取消和资源管理,避免内存泄漏。
  • 错误处理:将错误视为值,允许开发者以声明式的方式处理异常。
代码语言:javascript
代码运行次数:0
运行
复制
Produces a value of type number
         │  Fails with an Error
         │       │ Requires no dependencies
         ▼       ▼      ▼
Effect<number, Error, never>
安装与初始化

首先可以通过以下命令安装 Effect-TS 到你的项目:

代码语言:javascript
代码运行次数:0
运行
复制
pnpm add effect

Effect-TS 同时提供了一个命令行工具 create-effect-app,可以重新初始化一个新的项目:

代码语言:javascript
代码运行次数:0
运行
复制
pnpm create effect-app@latest

运行后,工具会引导你选择模板和配置 ESLint 等工具,生成一个预配置好的 Effect 项目!

初始化
初始化

初始化

第一个 Effect 程序
代码语言:javascript
代码运行次数:0
运行
复制
import { Console, Effect } from "effect";
const main = Console.log("Hello, World!");
Effect.runSync(main);

这里 Console.log 是一个 Effect 操作,Effect.runSync 是同步执行 Effect 的方法。

流式编码风格

pipe 是 Effect 库中用于流式组合操作的核心工具,它通过线性化的方式将 Effect 的操作符和函数连接起来,使代码更简洁、可读且符合函数式编程风格。

代码语言:javascript
代码运行次数:0
运行
复制
import { Effect } from "effect";

const program = Effect.succeed(42).pipe(
  Effect.map((n) => n * 2),
  Effect.map((n) => n + 10)
);
// 运行后得到:Effect<never, never, 94>
// 解释:42 先被 map 乘以 2 得到 84,再被 map 加上 10 得到 94
丰富的操作符

操作符(Operator)是指一类用于处理、转换或组合数据流(在这里是 Effect 值)的函数或方法。这些操作符通常以声明式的方式操作 Effect 对象,帮助开发者以函数式编程风格管理副作用、异步流程或复杂逻辑。

除了上面提到的 map,还要很多类似数组的操作方法,flatMapzip等等!

代码语言:javascript
代码运行次数:0
运行
复制
Effect.succeed(10)
  .pipe(Effect.flatMap((n) => Effect.succeed(n + 5))); 
// 结果:Effect<never, never, 15>

通常,我们需要和 pip 配合,将多个操作符组合起来

代码语言:javascript
代码运行次数:0
运行
复制
import { Effect } from "effect";

const program = Effect.succeed(10).pipe(
  Effect.map((n) => n * 2),
  Effect.flatMap((n) => Effect.succeed(n + 5)),
  Effect.map((n) => `Result: ${n}`)
);
// 结果:Effect<never, never, "Result: 25">
结构化并发

Effect-TS 的结构化并发确保所有异步任务都能被正确管理。例如,运行多个并发请求:

代码语言:javascript
代码运行次数:0
运行
复制
import { Effect } from "effect";

const program = Effect.all([
  getTodo(1),
  getTodo(2),
  getTodo(3)
]).pipe(
  Effect.tap((todos) => Console.log(`Fetched todos: ${JSON.stringify(todos)}`))
);

Effect.runPromise(program);

Effect.all 并行执行多个 Effect,并在所有任务完成时返回结果。如果某个任务失败,Effect 会自动清理其他任务,避免资源泄漏。

处理异步操作

Effect-TS 特别擅长处理异步逻辑。假设我们要从一个 API 获取数据,可以这样实现:

代码语言:javascript
代码运行次数:0
运行
复制
import { Effect, HttpClient } from "effect";

const getTodo = (id: number) =>
  HttpClient.get(`/todos/${id}`).pipe(
    Effect.andThen((response) => response.json)
  );

const program = getTodo(1).pipe(
  Effect.tap((data) => Console.log(`Fetched todo: ${JSON.stringify(data)}`)),
  Effect.catchAll((error) => Console.log(`Error: ${error.message}`))
);

Effect.runPromise(program);

这段代码定义了一个 getTodo 函数,使用 HttpClient 发送 GET 请求。使用 pipe 组合操作,通过 Effect.andThen 解析 JSON 响应。使用 Effect.tap 打印结果,Effect.catchAll 捕获并处理错误。 最后通过 Effect.runPromise 异步执行程序。

错误重试与超时

Effect-TS 内置了强大的错误处理和重试机制。例如,我们可以为 API 请求添加重试和超时逻辑:

代码语言:javascript
代码运行次数:0
运行
复制
import { Effect, Schedule } from "effect";

const robustGetTodo = (id: number) =>
  getTodo(id).pipe(
    Effect.retry(Schedule.exponential("100 millis", 2).pipe(Schedule.upTo(3))),
    Effect.timeout("1 second")
  );

const program = robustGetTodo(1).pipe(
  Effect.tap((data) => Console.log(`Success: ${JSON.stringify(data)}`)),
  Effect.catchAll((error) => Console.log(`Failed: ${error.message}`))
);

Effect.runPromise(program);

这里 Effect.retry 使用指数退避策略重试最多 3 次。Effect.timeout 设置 1 秒超时,超时后自动中止请求。所有这些操作都是声明式的,代码清晰且易于维护。

相较于 VueUse 或 ahooks 返回的错误类型通常是 unknown 或泛型,需要我们手动处理类型断言或错误边界!

最后

Effect-TS 不仅仅是一个核心库,它还有丰富的生态系统。感兴趣的小伙伴可以看这里

https://github.com/Effect-TS/effect?tab=readme-ov-file#monorepo-structure

生态
生态

生态

文章有限,我介绍了九牛一毛,感兴趣的同学可以看看文档:https://effect.website/docs

今天的分享就这些了,感谢大家的阅读,如果文章中存在错误的地方欢迎指正!

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-05-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萌萌哒草头将军 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 正文
    • 安装与初始化
    • 第一个 Effect 程序
    • 流式编码风格
    • 丰富的操作符
    • 结构化并发
    • 处理异步操作
    • 错误重试与超时
  • 最后
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档