
Effect v3 到 v4 被移除的 Runtime 与 Runtime.runFork 如何迁移到 runForkWith【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect升级 Effect 到 v4 后一类常见的 v3 代码会直接编译失败在 effect 内部通过Effect.runtimeR()取出运行时再调用Runtime.runFork(runtime)(program)在后台启动另一个带服务依赖的 effect。这段写法在 v4 中无法成立因为RuntimeR类型和Runtime.runFork都已被移除。官方迁移文档 migration/runtime.md 给出的替换路径是用ContextR承载服务把Runtime.runFork(runtime)换成Effect.runForkWith(services)。v4 中 Runtime 模块还剩什么v3 中RuntimeR是一个把ContextR、RuntimeFlags和FiberRefs打包在一起的单一值// v3 interface Runtimein R { readonly context: Context.ContextR readonly runtimeFlags: RuntimeFlags readonly fiberRefs: FiberRefs }v4 中这个类型不再存在用ContextR直接替代。运行函数全部挂在Effect上如Effect.runFork、Effect.runForkWithRuntime模块只剩进程生命周期相关的三个成员Teardown— 处理进程退出的接口defaultTeardown— 默认 teardown 实现makeRunMain— 创建平台特定的 main runner这意味着 v3 里通过 runtime 携带的运行标志、FiberRefs 等概念都不能原样照搬需要按 v4 的Context和独立 API 重写。迁移映射哪些调用换成什么完整映射见 migration/v3-to-v4.md 与 migration/annotations/effect__Runtime.yaml与本次迁移直接相关的条目v3 写法v4 替换说明Effect.runtimeR()Effect.contextR()捕获服务为Context配合对应的run*With函数使用Runtime.runFork(runtime)Effect.runForkWith(services)用原 Runtime 的 Context 运行无服务依赖时用Effect.runForkRuntime.make(...)Context.make构造传给Effect.run*With的服务 ContextRuntime#RuntimeR类型Context.Context直接携带 Context调用对应的Effect.run*WithEffect.runForkWith的签名定义在 Effect.tssince 4.0.0export const runForkWith: R( context: Context.ContextR ) A, E(effect: EffectA, E, R, options?: RunOptions | undefined) FiberA, E注意它是柯里化形式先传Context返回一个接收EffectA, E, R的函数。同时effect 的 R 需求必须被这个 Context 满足否则类型检查不过。完整迁移示例带服务的后台 effect下面是 migration/runtime.md 中的对照示例。v3 版本中main内部先取 runtime再用Runtime.runFork(runtime)(program)启动子 effect服务通过Effect.provideService提供v3 代码import { Context, Effect, Runtime } from effect class Logger extends Context.Tag(Logger)Logger, { readonly log: (message: string) void }() {} const program Effect.gen(function*() { const logger yield* Logger logger.log(Hello from Logger) }) const main Effect.gen(function*() { const runtime yield* Effect.runtimeLogger() return Runtime.runFork(runtime)(program) }).pipe( Effect.provideService(Logger, { log: (message) console.log(message) }) ) const fiber Effect.runFork(main)对应的 v4 写法三处改动yield* Effect.runtimeLogger()改为yield* Effect.contextLogger()拿到的services就是一个ContextRuntime.runFork(runtime)(program)改为Effect.runForkWith(services)(program)服务提供方从Effect.provideService(Logger, value)改为Effect.provideContext(Context.make(Logger, value))即先构造完整的 Context 再整体提供。v4 代码import { Context, Effect } from effect class Logger extends Context.ServiceLogger, { readonly log: (message: string) void }()(Logger) {} const program Effect.gen(function*() { const logger yield* Logger logger.log(Hello from Logger) }) const main Effect.gen(function*() { const services yield* Effect.contextLogger() return Effect.runForkWith(services)(program) }).pipe( Effect.provideContext(Context.make(Logger, { log: (message) console.log(message) })) ) const fiber Effect.runFork(main)迁移时容易遗漏的一点v3 的服务定义Context.Tag在 v4 示例中写成了Context.Service加显式标签字符串两处都要对齐 v4 的 API否则类型不匹配。effect 没有服务依赖时如果后台要启动的 effect 没有 R 需求不需要runForkWith直接用Effect.runFork(effect)即可这是runForkWith(Context.empty())的简写。文档中两条迁移备注都强调了这一点“Run with the former Runtimes Context; use Effect.runFork when no services are required.”验证迁移结果Effect.runForkWith返回FiberA, E用Fiber.join回到 Effect 域、再用Effect.runPromise取结果即可验证子 effect 真的执行了。Effect 源码中runForkWith的文档示例Effect.ts展示了完整的验证写法import { Context, Effect, Fiber } from effect const output: Arrayunknown [] interface Logger { log: (message: string) void } const Logger Context.ServiceLogger(Logger) const services Context.make(Logger, { log: (message) void output.push(message) }) const program Effect.gen(function*() { const logger yield* Logger logger.log(Hello from service!) return done }) const fiber Effect.runForkWith(services)(program) void output.push(await Effect.runPromise(Fiber.join(fiber))) output // 文档示例 [Hello from service!, done]最后一行的[Hello from service!, done]是文档示例输出Fiber.join完成后output中先有服务写下的Hello from service!再有 join 的返回值done说明子 effect 在提供了服务的 Context 下正确执行并返回了结果。同一模式的其它 Runner如果代码里除了runFork还用到了Runtime模块的其它运行函数替换规则一致——都改成Effect上的run*With并传入原 Runtime 的 Contextv3v4 替换Runtime.runPromise(runtime)Effect.runPromiseWithRuntime.runSync(runtime)Effect.runSyncWithRuntime.runCallback(runtime)Effect.runCallbackWithRuntime.runPromiseExit(runtime)Effect.runPromiseExitWithRuntime.runSyncExit(runtime)Effect.runSyncExitWith另外v3 的RuntimeFlags概念整体被移除不再随 runtime 传递需要控制调度、可中断性或运行时指标时要按 v4 提供的独立配置项分别设置而不是恢复一个聚合的 flags 对象。参考资料本次迁移的专题文档migration/runtime.md完整的 v3 到 v4 API 映射由 API diff 生成migration/v3-to-v4.mdRuntime模块逐项替换说明migration/annotations/effect__Runtime.yamlv4 中Effect.runForkWith的定义与用法示例packages/effect/src/Effect.ts【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考