ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

Effect 新增 Effect.abortSignal:在作用域内安全获取并传递取消信号(AbortSignal)

Effect 新增 Effect.abortSignal:在作用域内安全获取并传递取消信号(AbortSignal) Effect 新增 Effect.abortSignal在作用域内安全获取并传递取消信号AbortSignal【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect导读Effect 库TypeScript 生产级应用框架在其 4.0 版本新增了Effect.abortSignal这一中断interruption相关 API用于在 Effect 作用域Scope内获取一个由作用域生命周期托管的AbortSignal从而把 Effect 的取消语义桥接到fetch、WebSocket、文件读取等原生接受AbortSignal的异步 API。读完本文你将理解该 API 的签名、底层实现原理acquireRelease资源管理、正确用法与作用域关闭时的取消行为并能在自己的 Effect 程序中安全落地。变更来源一条 changeset 背后的新 API本仓库通过 .changeset/pre/few-cougars-dig.md 这类 changeset 文件管理发布日志该文件的完整内容如下--- effect: patch --- add Effect.abortSignal它声明effect主包以patch补丁级别发布一条变更——新增Effect.abortSignal。对应地packages/effect/CHANGELOG.md 中的发布记录也确认了这一 API 的引入。在源码中该 API 标注的版本为since 4.0.0说明它随 Effect 4.0 系列正式对外。API 签名与核心行为Effect.abortSignal的公开签名位于 packages/effect/src/Effect.ts#L7485归类为interruption中断类别export const abortSignal: EffectAbortSignal, never, Scope其类型含义可以拆解为类型参数含义AbortSignal成功产出值一个AbortSignal实例never不会以类型化错误typed error失败Scope环境需求必须在某个作用域内运行由作用域决定信号生命周期根据该 API 的 JSDocpackages/effect/src/Effect.ts#L7461-L7484其行为要点如下每次获取都创建全新的AbortController不会共享、复用外部控制器保证每个调用方拿到独立信号关闭所属作用域时会执行终结器finalizer即调用controller.abort()从而向所有监听该信号的异步操作发出取消通知效果成功产出该控制器的signal你拿到信号后可直接传给接受AbortSignal的原生 API。JSDoc 同时给出了一条重要告诫Gotchas信号在其所属作用域关闭时即被中止因此不要让使用该信号的异步工作超出该作用域的生命周期否则工作会在中途被取消。底层实现基于 acquireRelease 的资源生命周期Effect.abortSignal的内部实现非常精简位于 packages/effect/src/internal/effect.ts#L4580-L4586export const abortSignal: Effect.EffectAbortSignal, never, Scope.Scope map( acquireRelease( sync(() new AbortController()), (controller) sync(() controller.abort()) ), (_) _.signal )实现可分为三层理解获取资源acquiresync(() new AbortController())在获取时同步创建一个全新的AbortController。这里使用sync同步求值而非suspend因为创建控制器本身是零开销的纯构造操作释放资源release(controller) sync(() controller.abort())注册终结器——当作用域关闭无论正常完成还是被中断时Effect 会执行该终结器调用controller.abort()广播取消信号映射产出值map(_) _.signal把AbortController映射为它的signal属性作为效果的成功值返回给调用方。从实现可以推断该 API 复用了 Effect 既有的资源管理原语acquireRelease同一源码文件中实现因此信号的创建、中止与作用域生命周期严格绑定且中止逻辑是同步、无副作用的简单调用不依赖任何外部事件循环机制——这正是它能与 Effect 结构化并发、确定性的取消模型保持一致的原因。实战用法把取消信号接入 fetchEffect.abortSignal的典型应用场景是把 Effect 的取消语义传递给那些只认识AbortSignal的宿主环境 API。下面是一个接入fetch的完整示例fetch 是唯一支持AbortSignal做请求取消的浏览器/Node 原生 API 之一import { Effect } from effect const program Effect.gen(function*() { // 在作用域内获取一个由作用域托管的 AbortSignal const signal yield* Effect.abortSignal // 将信号传给 fetch使请求支持取消 const response yield* Effect.tryPromise({ try: () fetch(https://example.com/data, { signal }), catch: (unknown) new Error(fetch failed: ${String(unknown)}) }) return response }) // Effect.abortSignal 需要 Scope 环境 // 使用 Effect.scoped 把运行期绑定到独立作用域 const runnable Effect.scoped(program)要点说明环境需求Scope由于Effect.abortSignal的类型要求Scope直接运行会缺少依赖。最常见的做法是像示例一样用Effect.scoped包裹使效果整体在一个受控作用域内运行作用域关闭时AbortController的终结器自动执行取消链路当外层 Effect 被中断例如 Fiber 被Fiber.interrupt中断或运行作用域被关闭时作用域关闭会触发controller.abort()fetch随即以AbortError拒绝从而把 Effect 的取消事件透传到真实的网络请求层错误处理fetch在信号中止时会抛出AbortErrorEffect.tryPromise会将其捕获并转换为Error保证中断不会以未捕获异常的形式泄漏。与其他中断机制的协同Effect.abortSignal并非替代 Effect 自有的中断模型而是把 Effect 的中断翻译成宿主环境的AbortSignal语义二者协作关系如下场景Effect 原生机制abortSignal 的补充取消一个 Effect 程序Fiber.interrupt、作用域关闭触发结构化取消通过作用域关闭触发controller.abort()在取消时执行清理Effect.onInterrupt/Effect.addFinalizer终结器controller.abort()本身就是注册到作用域的资源终结器对接不支持 Effect 的原生异步 API无法直接传递取消意图把AbortSignal交给fetch等 API实现取消透传从源码位置看abortSignal与uninterruptibleMask、interruptibleMask等中断原语同属 packages/effect/src/internal/effect.ts 的中断相关实现区域并在公开 API 中归类于category interruption说明其定位就是中断/取消能力的一部分。注意事项与边界信号生命周期以作用域为准JSDoc 明确提示信号在所属作用域关闭时即被中止因此禁止将该信号用于超出作用域存活期的异步工作例如在作用域外继续使用该信号发起后续请求否则会收到意外的取消每个获取都是独立控制器每次yield* Effect.abortSignal都会新建AbortController因此同一作用域内多次获取得到的是互相独立的信号互不干扰与Effect.scoped的关系JSDoc 通过see指向scoped建议读者把Effect.scoped作为绑定资源生命周期的标准入口对应文档目录可见 ai-docs/src/01_effect/06_running 对运行与作用域的配套讲解版本前提该 API 标注since 4.0.0使用前请确认effect依赖版本不低于 4.0.0变更级别为 patch属于向后兼容的增量能力不影响既有代码。小结Effect.abortSignal以约 7 行实现packages/effect/src/internal/effect.ts#L4580-L4586为 Effect 程序提供了一条通往AbortSignal生态的标准化通道通过acquireRelease把AbortController的创建与中止绑定到作用域生命周期再以map暴露signal。它让 fetch、WebSocket 等原生异步 API 可以无缝接入 Effect 的结构化取消模型是编写生产级 TypeScript 应用时处理取消语义的实用补充。【免费下载链接】effectBuild production-ready applications in TypeScript项目地址: https://gitcode.com/GitHub_Trending/ef/effect创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表