已发布 上游基线 bf46254 原文 ↗ 在 GitHub 编辑

默认服务

了解 Effect 中的默认服务,包括 Clock、Console、Random、ConfigProvider 和 Tracer,以及它们如何被自动提供给我们的程序。

Effect 自带五种预置服务:

type DefaultServices = Clock | ConfigProvider | Console | Random | Tracer

当我们使用这些服务时,无需显式提供它们的实现。Effect 会自动把它们的 live 版本提供给我们的 effect,让我们省去手动配置的麻烦。

示例(使用 Clock 和 Console)

import { Effect, Clock, Console } from "effect"

//      ┌─── Effect<void, never, never>
//      ▼
const program = Effect.gen(function* () {
  const now = yield* Clock.currentTimeMillis
  yield* Console.log(`Application started at ${new Date(now)}`)
})

Effect.runFork(program)
// Output: Application started at <current time>

可以看到,即使我们的程序同时使用了 ClockConsole,代表该 effect 执行所需服务的 Requirements 参数依然保持为 never。 Effect 会替我们无缝地处理这些服务。

覆盖默认服务

有时你可能需要用自定义实现来替换默认服务。Effect 提供了内置工具,可用 Effect.with<service>Effect.with<service>Scoped 覆盖这些服务。

  • Effect.with<service>:在 effect 的持续期间内覆盖某个服务。
  • Effect.with<service>Scoped:在某个 scope 内覆盖服务,并在之后恢复原来的服务。
函数说明
Effect.withClock使用指定的 Clock 服务执行 effect。
Effect.withClockScoped临时覆盖 Clock 服务,并在 scope 结束时恢复它。
Effect.withConfigProvider使用指定的 ConfigProvider 服务执行 effect。
Effect.withConfigProviderScoped在某个 scope 内临时覆盖 ConfigProvider 服务。
Effect.withConsole使用指定的 Console 服务执行 effect。
Effect.withConsoleScoped在某个 scope 内临时覆盖 Console 服务。
Effect.withRandom使用指定的 Random 服务执行 effect。
Effect.withRandomScoped在某个 scope 内临时覆盖 Random 服务。
Effect.withTracer使用指定的 Tracer 服务执行 effect。
Effect.withTracerScoped在某个 scope 内临时覆盖 Tracer 服务。

示例(覆盖 Random 服务)

import { Effect, Random } from "effect"

// A program that logs a random number
const program = Effect.gen(function* () {
  console.log(yield* Random.next)
})

Effect.runSync(program)
// Example Output: 0.23208633934454326 (varies each run)

// Override the Random service with a seeded generator
const override = program.pipe(Effect.withRandom(Random.make("myseed")))

Effect.runSync(override)
// Output: 0.6862142528438508 (consistent output with the seed)