并发与运行时底层
L17 Fiber:虚拟线程与运行中的 Effect
本课目标
- 区分 Effect 与 Fiber
- 掌握 join / await / interrupt 的语义差别
前置课时尚未完成:L08
可以自行跳转学习,但按顺序推进会更省力;学情分析会把这类缺口归入「前置缺口」。
一个是蓝图,一个是执行
JavaScript 本身单线程,Fiber 是 runtime 模拟出来的逻辑线程。每次运行 effect 都会创建一个 fiber;即便没有显式并发,也至少有一个 main fiber。并发时每个并发任务各有一个 fiber。Fiber<Success, Error> 没有 R 参数,因为它执行的是依赖已被提供完的 effect。
fork / join / await
← 代码可左右滑动 →
import { Effect, Fiber, Exit } from "effect"
const program = Effect.gen(function* () {
const fiber = yield* Effect.forkChild(Effect.succeed(55))
const value = yield* Fiber.join(fiber) // 取结果
const exit = yield* Fiber.await(fiber) // 取 Exit 完成详情
// exit => Exit.succeed(55)
return value
})💡 v4 中 Fiber 不再是 Effect:不能直接 yield* fiber,必须 Fiber.join(fiber)。Ref / Deferred 同理,用 Ref.get / Deferred.await。
⚠️ fork 出去不是立刻开跑
官方明确:forked fibers 在当前 fiber 完成或让出后才开始执行,且启动时机不确定。Effect.sleep() / Effect.yieldNow() 可以给它们机会,但不要依赖「单次 yield 一定够」做同步假设。
交互演练
关键术语
虚拟线程
由 runtime 在单线程上模拟的逻辑执行单元
Fiber handle
对一次运行中计算的引用,可 join / await / interrupt
常见误区
× 把 Fiber 直接 yield*,或把它当成 Promise 去 await。
随堂测验(即时反馈,答题计入掌握度)
Q1Fiber<A, E> 为什么没有 R 参数?
Q2想拿到 fiber 的失败/中断详情用?