用途:该技能为构建生产级 Effect-TS 应用提供规则、约定与架构决策,带有明确倾向性,用于规避常见陷阱并推行可扩展的模式。它侧重「如何与为何」惯用 Effect,而非完整 API 文档;查询详细 API 建议使用文档检索或网络搜索。
主要能力: 一、核心约定。业务逻辑用 Effect.gen,生成器读起来接近同步代码,优于冗长的 pipe/flatMap 链;pipe 保留给数据转换管道和短组合子链。不要 throw,改用错误通道:Effect.fail、Effect.tryPromise、Effect.async、Effect.die。优先函数式写法,如 Effect.map(e, f)。@effect/schema 已弃用,Schema 已并入核心 effect,应从 "effect" 直接导入。生产环境用 NodeRuntime.runMain,因为 Effect.runPromise 不优雅处理 SIGINT/SIGTERM。 二、错误处理。区分失败(预期,进入 E 通道,可 catchTag/catchAll/retry)与缺陷(意外,不进 E,仅在系统边界恢复)。始终使用 Data.TaggedError 定义标签化错误,标签化错误可直接 yield,无需 Effect.fail 包裹。注意 catchAll 只捕获 E,不捕获缺陷;catchAllCause 才捕获全部,应仅在顶层处理器或 HTTP 响应映射等边界使用。 三、依赖注入。遵循 Service → Layer → Provide:用 Context.Tag 定义服务,用 Layer 实现,在入口点提供一次。服务方法的 R 必须为 never,依赖放在 Layer 组合中而非方法签名。熟悉操作符:Layer.merge 用于独立服务并行构建;Layer.provide 用于 A 供给 B 的场景,注意 merge 不保证构建顺序;Layer.fresh 绕过记忆化强制新实例。避免在代码各处散落 Effect.provide。 四、资源与作用域。使用 acquireRelease 时必须配合 Effect.scoped,否则资源会累积直至程序退出。释放 finalizer 在成功、失败与中断时都会运行,并按获取的逆序释放。 五、并发。优先使用高层 API:Effect.all 带 concurrency 做有界并行、Effect.forEach 做工作池、Effect.race、Effect.timeout;仅在高层次 API 不足时才用 fork。fork 变体生命周期不同:fork 随父作用域自动中断,forkDaemon 属全局作用域需手动清理,forkScoped 绑定最近 Scope。
常见陷阱:浮动 effect(创建但未 yield 或运行)是静默 bug;catchAll 不捕缺陷;缺失 Effect.scoped 泄漏资源;散落的 provide;对重载函数使用 point-free 写法会抹除泛型;Effect.async 的 resume 必须且只能调用一次;orDie 会把类型化失败变为缺陷;对依赖服务用 Layer.merge 而非 Layer.provide;资源安全场景优先 Fiber.await 而非 join;无限流上调用 runCollect 不会终止;需要 Scope 的测试要用 it.scoped 而非 it.effect。
参考文件:按关注点查阅 references 下的 error-handling.md、dependency-injection.md、concurrency.md、resource-management.md、schema.md、stream.md、testing.md、platform.md。
限制:资料仅描述约定与陷阱,未提供收费、价格、平台支持或效果验证信息,相关事实暂未提供。