Exit
用 Exit 表示 Effect 工作流的运行结果,捕获成功值或失败原因。
一个 Exit<A, E> 描述了一次 Effect 工作流运行的结果。
Exit<A, E> 有两种可能的状态:
Exit.Success:包含类型为A的成功值。Exit.Failure:包含类型为E的失败 Cause。
创建 Exit
Exit 模块提供了两个用于构造 Exit 值的主要函数:Exit.succeed 和 Exit.failCause。
这两个函数分别以成功或失败的形式,表示一次 effectful 计算的结果。
succeed
Exit.succeed 创建一个表示成功结果的 Exit 值。
当你想表明一次计算成功完成,并提供其计算结果时,就可以使用这个函数。
示例(创建一个成功的 Exit)
import { Exit } from "effect"
// Create an Exit representing a successful outcome with the value 42
//
// ┌─── Exit<number, never>
// ▼
const successExit = Exit.succeed(42)
console.log(successExit)
successExit // => Exit.succeed(42)
failCause
Exit.failCause 创建一个表示失败的 Exit 值。
失败通过一个 Cause 对象来描述,该对象可以封装预期内的错误、defect、中断,甚至是复合错误。
示例(创建一个失败的 Exit)
import { Exit, Cause } from "effect"
// Create an Exit representing a failure with an error message
//
// ┌─── Exit<never, string>
// ▼
const failureExit = Exit.failCause(Cause.fail("Something went wrong"))
console.log(failureExit)
failureExit // => Exit.fail("Something went wrong")
模式匹配
你可以使用 Exit.match 函数处理 Exit 的不同结果。
该函数允许你提供两个独立的回调,分别处理一次 Effect 执行的成功与失败情况。
示例(同时匹配成功与失败状态)
import { Effect, Exit, Cause } from "effect"
// ┌─── Exit<number, never>
// ▼
const simulatedSuccess = Effect.runSyncExit(Effect.succeed(1))
console.log(
Exit.match(simulatedSuccess, {
onFailure: (cause) => `Exited with failure state: ${Cause.pretty(cause)}`,
onSuccess: (value) => `Exited with success value: ${value}`,
}),
)
Exit.match(simulatedSuccess, {
onFailure: (cause) => `Exited with failure state: ${Cause.pretty(cause)}`,
onSuccess: (value) => `Exited with success value: ${value}`,
}) // => "Exited with success value: 1"
// ┌─── Exit<never, string>
// ▼
const simulatedFailure = Effect.runSyncExit(
Effect.failCause(Cause.fail("error")),
)
console.log(
Exit.match(simulatedFailure, {
onFailure: (cause) => `Exited with failure state: ${Cause.pretty(cause)}`,
onSuccess: (value) => `Exited with success value: ${value}`,
}),
)
/*
Output:
Exited with failure state: Error: error
...stack trace...
*/
Exit.match(simulatedFailure, {
onFailure: (cause) => `Exited with failure state: ${Cause.pretty(cause)}`,
onSuccess: (value) => `Exited with success value: ${value}`,
}).split("\n")[0] // => "Exited with failure state: Error: error"
Exit 与 Result 的对比
从概念上讲,Exit<A, E> 可以看作 Result<A, Cause<E>>。不过 Cause 类型所表示的并不只是类型为 E 的预期错误,它还包括:
- 中断原因
- Defect(非预期的错误)
- 多个 Cause 的组合
这让 Cause 相比简单的 Result 能够捕获更丰富、更复杂的错误状态。
Exit 与 Effect 的对比
Exit 实际上是 Effect 的子类型。这意味着 Exit 值也可以被视为 Effect 值。
- 从本质上讲,一个
Exit就是一次“常量计算”。 Effect.succeed本质上等同于Exit.succeed。Effect.failCause等同于Exit.failCause。