Skip to content

延迟值

一个 Deferred<Success, Error>Effect 的专门子类型,它像一个具有一些独特特征的一次性变量。它只能完成一次,使其成为管理异步操作和程序不同部分之间同步的有用工具。

延迟值本质上是一个同步原语,表示一个可能不会立即可用的值。当您创建延迟值时,它开始是空的。稍后,它可以用成功值 Success 或错误值 Error 完成:

┌─── Represents the success type
│ ┌─── Represents the error type
│ │
▼ ▼
Deferred<Success, Error>

一旦完成,就不能再次更改。

当纤程调用 Deferred.await 时,它将暂停直到延迟值完成。当纤程等待时,它不会阻塞线程,只是在语义上阻塞。这意味着其他纤程仍然可以运行,确保高效的并发。

延迟值在概念上类似于 JavaScript 的 Promise。 关键区别在于它支持成功和错误类型,提供更多的类型安全性。

可以使用 Deferred.make 构造函数创建延迟值。这返回一个表示延迟值创建的 effect。由于延迟值的创建涉及内存分配,必须在 effect 内完成以确保资源的安全管理。

示例(创建延迟值)

import {
import Deferred
Deferred
} from "effect"
// ┌─── Effect<Deferred<string, Error>>
// ▼
const
const deferred: Effect<Deferred.Deferred<string, Error>, never, never>
deferred
=
import Deferred
Deferred
.
const make: <string, Error>() => Effect<Deferred.Deferred<string, Error>, never, never>

Creates a new Deferred.

@since2.0.0

make
<string,
interface Error
Error
>()

要从延迟值中检索值,您可以使用 Deferred.await。此操作会暂停调用纤程,直到延迟值完成并返回值或错误。

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Deferred
Deferred
} from "effect"
// ┌─── Effect<Deferred<string, Error>, never, never>
// ▼
const
const deferred: Effect.Effect<Deferred.Deferred<string, Error>, never, never>
deferred
=
import Deferred
Deferred
.
const make: <string, Error>() => Effect.Effect<Deferred.Deferred<string, Error>, never, never>

Creates a new Deferred.

@since2.0.0

make
<string,
interface Error
Error
>()
// ┌─── Effect<string, Error, never>
// ▼
const
const value: Effect.Effect<string, Error, never>
value
=
const deferred: Effect.Effect<Deferred.Deferred<string, Error>, never, never>
deferred
.
Pipeable.pipe<Effect.Effect<Deferred.Deferred<string, Error>, never, never>, Effect.Effect<string, Error, never>>(this: Effect.Effect<Deferred.Deferred<string, Error>, never, never>, ab: (_: Effect.Effect<Deferred.Deferred<string, Error>, never, never>) => Effect.Effect<string, Error, never>): Effect.Effect<string, Error, never> (+21 overloads)
pipe
(
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const andThen: <Deferred.Deferred<string, Error>, Effect.Effect<string, Error, never>>(f: (a: Deferred.Deferred<string, Error>) => Effect.Effect<string, Error, never>) => <E, R>(self: Effect.Effect<Deferred.Deferred<string, Error>, E, R>) => Effect.Effect<string, Error | E, R> (+3 overloads)

Chains two actions, where the second action can depend on the result of the first.

Syntax

const transformedEffect = pipe(myEffect, Effect.andThen(anotherEffect))
// or
const transformedEffect = Effect.andThen(myEffect, anotherEffect)
// or
const transformedEffect = myEffect.pipe(Effect.andThen(anotherEffect))

When to Use

Use andThen when you need to run multiple actions in sequence, with the second action depending on the result of the first. This is useful for combining effects or handling computations that must happen in order.

Details

The second action can be:

  • A constant value (similar to

as

)

  • A function returning a value (similar to

map

)

  • A Promise
  • A function returning a Promise
  • An Effect
  • A function returning an Effect (similar to

flatMap

)

Note: andThen works well with both Option and Either types, treating them as effects.

Example (Applying a Discount Based on Fetched Amount)

import { pipe, Effect } from "effect"
// Function to apply a discount safely to a transaction amount
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
// Simulated asynchronous task to fetch a transaction amount from database
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
// Using Effect.map and Effect.flatMap
const result1 = pipe(
fetchTransactionAmount,
Effect.map((amount) => amount * 2),
Effect.flatMap((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(result1).then(console.log)
// Output: 190
// Using Effect.andThen
const result2 = pipe(
fetchTransactionAmount,
Effect.andThen((amount) => amount * 2),
Effect.andThen((amount) => applyDiscount(amount, 5))
)
Effect.runPromise(result2).then(console.log)
// Output: 190

@since2.0.0

andThen
(
import Deferred
Deferred
.
const await: <A, E>(self: Deferred.Deferred<A, E>) => Effect.Effect<A, E>
export await

Retrieves the value of the Deferred, suspending the fiber running the workflow until the result is available.

@since2.0.0

await
))

您可以通过多种方式完成延迟值,具体取决于您是否要成功、失败或中断等待的纤程:

API描述
Deferred.succeed使用值成功完成延迟值。
Deferred.done使用 Exit 值完成延迟值。
Deferred.complete使用 effect 的结果完成延迟值。
Deferred.completeWith使用 effect 完成延迟值。此 effect 将由每个等待的纤程执行,因此请谨慎使用。
Deferred.fail使用错误使延迟值失败。
Deferred.die使用用户定义的错误使延迟值缺陷。
Deferred.failCause使用 Cause 使延迟值失败或缺陷。
Deferred.interrupt中断延迟值,强制停止或中断等待的纤程。

示例(成功完成延迟值)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Deferred
Deferred
} from "effect"
const
const program: Effect.Effect<void, string, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Deferred.Deferred<number, string>, never, never>> | YieldWrap<Effect.Effect<boolean, never, never>> | YieldWrap<Effect.Effect<number, string, never>>, void>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<Deferred.Deferred<number, string>, never, never>> | YieldWrap<Effect.Effect<boolean, never, never>> | YieldWrap<Effect.Effect<number, string, never>>, void, never>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const deferred: Deferred.Deferred<number, string>
deferred
= yield*
import Deferred
Deferred
.
const make: <number, string>() => Effect.Effect<Deferred.Deferred<number, string>, never, never>

Creates a new Deferred.

@since2.0.0

make
<number, string>()
// 成功完成延迟值
yield*
import Deferred
Deferred
.
const succeed: <number, string>(self: Deferred.Deferred<number, string>, value: number) => Effect.Effect<boolean> (+1 overload)

Completes the Deferred with the specified value.

@since2.0.0

succeed
(
const deferred: Deferred.Deferred<number, string>
deferred
, 1)
// 等待延迟值以获取其值
const
const value: number
value
= yield*
import Deferred
Deferred
.
await<number, string>(self: Deferred.Deferred<number, string>): Effect.Effect<number, string, never>
export await

Retrieves the value of the Deferred, suspending the fiber running the workflow until the result is available.

@since2.0.0

await
(
const deferred: Deferred.Deferred<number, string>
deferred
)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const value: number
value
)
})
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <void, string>(effect: Effect.Effect<void, string, never>, options?: RunForkOptions) => RuntimeFiber<void, string>

Runs an effect in the background, returning a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

Details

This function is the foundational way to execute an effect in the background. It creates a "fiber," a lightweight, cooperative thread of execution that can be observed (to access its result), interrupted, or joined. Fibers are useful for concurrent programming and allow effects to run independently of the main program flow.

Once the effect is running in a fiber, you can monitor its progress, cancel it if necessary, or retrieve its result when it completes. If the effect fails, the fiber will propagate the failure, which you can observe and handle.

When to Use

Use this function when you need to run an effect in the background, especially if the effect is long-running or performs periodic tasks. It's suitable for tasks that need to run independently but might still need observation or management, like logging, monitoring, or scheduled tasks.

This function is ideal if you don't need the result immediately or if the effect is part of a larger concurrent workflow.

Example (Running an Effect in the Background)

import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: Effect.Effect<void, string, never>
program
)
// 输出: 1

完成延迟值会产生一个 Effect<boolean>。如果延迟值成功完成,此 effect 返回 true,如果之前已经完成,则返回 false。这对于跟踪延迟值的状态很有用。

示例(检查完成状态)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Deferred
Deferred
} from "effect"
const
const program: Effect.Effect<void, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Deferred.Deferred<number, string>, never, never>> | YieldWrap<Effect.Effect<boolean, never, never>>, void>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<Deferred.Deferred<number, string>, never, never>> | YieldWrap<Effect.Effect<boolean, never, never>>, void, never>) => Effect.Effect<void, never, never> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const deferred: Deferred.Deferred<number, string>
deferred
= yield*
import Deferred
Deferred
.
const make: <number, string>() => Effect.Effect<Deferred.Deferred<number, string>, never, never>

Creates a new Deferred.

@since2.0.0

make
<number, string>()
// 尝试使延迟值失败
const
const firstAttempt: boolean
firstAttempt
= yield*
import Deferred
Deferred
.
const fail: <number, string>(self: Deferred.Deferred<number, string>, error: string) => Effect.Effect<boolean> (+1 overload)

Fails the Deferred with the specified error, which will be propagated to all fibers waiting on the value of the Deferred.

@since2.0.0

fail
(
const deferred: Deferred.Deferred<number, string>
deferred
, "oh no!")
// 在已经完成后尝试成功
const
const secondAttempt: boolean
secondAttempt
= yield*
import Deferred
Deferred
.
const succeed: <number, string>(self: Deferred.Deferred<number, string>, value: number) => Effect.Effect<boolean> (+1 overload)

Completes the Deferred with the specified value.

@since2.0.0

succeed
(
const deferred: Deferred.Deferred<number, string>
deferred
, 1)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
([
const firstAttempt: boolean
firstAttempt
,
const secondAttempt: boolean
secondAttempt
])
})
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <void, never>(effect: Effect.Effect<void, never, never>, options?: RunForkOptions) => RuntimeFiber<void, never>

Runs an effect in the background, returning a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

Details

This function is the foundational way to execute an effect in the background. It creates a "fiber," a lightweight, cooperative thread of execution that can be observed (to access its result), interrupted, or joined. Fibers are useful for concurrent programming and allow effects to run independently of the main program flow.

Once the effect is running in a fiber, you can monitor its progress, cancel it if necessary, or retrieve its result when it completes. If the effect fails, the fiber will propagate the failure, which you can observe and handle.

When to Use

Use this function when you need to run an effect in the background, especially if the effect is long-running or performs periodic tasks. It's suitable for tasks that need to run independently but might still need observation or management, like logging, monitoring, or scheduled tasks.

This function is ideal if you don't need the result immediately or if the effect is part of a larger concurrent workflow.

Example (Running an Effect in the Background)

import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: Effect.Effect<void, never, never>
program
)
// 输出: [ true, false ]

有时,您可能需要检查延迟值是否已完成而不暂停纤程。这可以使用 Deferred.poll 方法来完成。它的工作原理如下:

  • Deferred.poll 返回一个 Option<Effect<A, E>>
    • 如果 Deferred 未完成,它返回 None
    • 如果 Deferred 已完成,它返回 Some,其中包含结果或错误。

此外,您可以使用 Deferred.isDone 函数来检查延迟值是否已完成。此方法返回一个 Effect<boolean>,如果 Deferred 已完成,则计算为 true,允许您快速检查其状态。

示例(轮询和检查完成状态)

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Deferred
Deferred
} from "effect"
const
const program: Effect.Effect<void, never, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Deferred.Deferred<number, string>, never, never>> | YieldWrap<Effect.Effect<Option<Effect.Effect<number, string, never>>, never, never>> | YieldWrap<Effect.Effect<boolean, never, never>>, void>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<Deferred.Deferred<number, string>, never, never>> | YieldWrap<Effect.Effect<Option<Effect.Effect<number, string, never>>, never, never>> | YieldWrap<...>, void, never>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const deferred: Deferred.Deferred<number, string>
deferred
= yield*
import Deferred
Deferred
.
const make: <number, string>() => Effect.Effect<Deferred.Deferred<number, string>, never, never>

Creates a new Deferred.

@since2.0.0

make
<number, string>()
// 轮询延迟值以检查是否已完成
const
const done1: Option<Effect.Effect<number, string, never>>
done1
= yield*
import Deferred
Deferred
.
const poll: <number, string>(self: Deferred.Deferred<number, string>) => Effect.Effect<Option<Effect.Effect<number, string, never>>, never, never>

Returns a Some<Effect<A, E, R>> from the Deferred if this Deferred has already been completed, None otherwise.

@since2.0.0

poll
(
const deferred: Deferred.Deferred<number, string>
deferred
)
// 检查延迟值是否已完成
const
const done2: boolean
done2
= yield*
import Deferred
Deferred
.
const isDone: <number, string>(self: Deferred.Deferred<number, string>) => Effect.Effect<boolean>

Returns true if this Deferred has already been completed with a value or an error, false otherwise.

@since2.0.0

isDone
(
const deferred: Deferred.Deferred<number, string>
deferred
)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
([
const done1: Option<Effect.Effect<number, string, never>>
done1
,
const done2: boolean
done2
])
})
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <void, never>(effect: Effect.Effect<void, never, never>, options?: RunForkOptions) => RuntimeFiber<void, never>

Runs an effect in the background, returning a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

Details

This function is the foundational way to execute an effect in the background. It creates a "fiber," a lightweight, cooperative thread of execution that can be observed (to access its result), interrupted, or joined. Fibers are useful for concurrent programming and allow effects to run independently of the main program flow.

Once the effect is running in a fiber, you can monitor its progress, cancel it if necessary, or retrieve its result when it completes. If the effect fails, the fiber will propagate the failure, which you can observe and handle.

When to Use

Use this function when you need to run an effect in the background, especially if the effect is long-running or performs periodic tasks. It's suitable for tasks that need to run independently but might still need observation or management, like logging, monitoring, or scheduled tasks.

This function is ideal if you don't need the result immediately or if the effect is part of a larger concurrent workflow.

Example (Running an Effect in the Background)

import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: Effect.Effect<void, never, never>
program
)
/*
输出:
[ { _id: 'Option', _tag: 'None' }, false ]
*/

当您需要等待程序中发生特定事情时,Deferred 变得很有用。 它非常适合您希望代码的一部分在准备就绪时向另一部分发出信号的场景。

以下是一些常见用例:

用例描述
协调纤程当您有多个并发任务并需要协调它们的操作时,Deferred 可以帮助一个纤程在完成任务时向另一个纤程发出信号。
同步任何时候您想确保一段代码在另一段代码完成工作之前不会继续执行,Deferred 可以提供您需要的同步。
工作交接您可以使用 Deferred 将工作从一个纤程交给另一个纤程。例如,一个纤程可以准备一些数据,然后第二个纤程可以继续处理它。
暂停执行当您希望纤程暂停执行直到满足某些条件时,可以使用 Deferred 阻塞它直到条件满足。

示例(使用延迟值协调两个纤程)

在此示例中,延迟值用于在两个纤程之间传递值。

通过并发运行两个纤程并使用延迟值作为同步点,我们可以确保 fiberB 仅在 fiberA 完成其任务后才继续。

import {
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
,
import Deferred
Deferred
,
import Fiber
Fiber
} from "effect"
const
const program: Effect.Effect<void, string, never>
program
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<Deferred.Deferred<string, string>, never, never>> | YieldWrap<Effect.Effect<Fiber.RuntimeFiber<boolean, never>, never, never>> | YieldWrap<Effect.Effect<Fiber.RuntimeFiber<string, string>, never, never>> | YieldWrap<Effect.Effect<[boolean, string], string, never>>, void>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<Deferred.Deferred<string, string>, never, never>> | YieldWrap<...> | YieldWrap<...> | YieldWrap<...>, void, never>) => Effect.Effect<...> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
const
const deferred: Deferred.Deferred<string, string>
deferred
= yield*
import Deferred
Deferred
.
const make: <string, string>() => Effect.Effect<Deferred.Deferred<string, string>, never, never>

Creates a new Deferred.

@since2.0.0

make
<string, string>()
// 延迟后使用值完成延迟值
const
const taskA: Effect.Effect<boolean, never, never>
taskA
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<void, never, never>>, boolean>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<void, never, never>>, boolean, never>) => Effect.Effect<boolean, never, never> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("开始完成延迟值的任务")
yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const sleep: (duration: DurationInput) => Effect.Effect<void>

Suspends the execution of an effect for a specified Duration.

Details

This function pauses the execution of an effect for a given duration. It is asynchronous, meaning that it does not block the fiber executing the effect. Instead, the fiber is suspended during the delay period and can resume once the specified time has passed.

The duration can be specified using various formats supported by the Duration module, such as a string ("2 seconds") or numeric value representing milliseconds.

Example

import { Effect } from "effect"
const program = Effect.gen(function*() {
console.log("Starting task...")
yield* Effect.sleep("3 seconds") // Waits for 3 seconds
console.log("Task completed!")
})
Effect.runFork(program)
// Output:
// Starting task...
// Task completed!

@since2.0.0

sleep
("1 second")
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("完成延迟值")
return yield*
import Deferred
Deferred
.
const succeed: <string, string>(self: Deferred.Deferred<string, string>, value: string) => Effect.Effect<boolean> (+1 overload)

Completes the Deferred with the specified value.

@since2.0.0

succeed
(
const deferred: Deferred.Deferred<string, string>
deferred
, "hello world")
})
// 等待延迟值并打印值
const
const taskB: Effect.Effect<string, string, never>
taskB
=
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const gen: <YieldWrap<Effect.Effect<string, string, never>>, string>(f: (resume: Effect.Adapter) => Generator<YieldWrap<Effect.Effect<string, string, never>>, string, never>) => Effect.Effect<string, string, never> (+1 overload)

Provides a way to write effectful code using generator functions, simplifying control flow and error handling.

When to Use

Effect.gen allows you to write code that looks and behaves like synchronous code, but it can handle asynchronous tasks, errors, and complex control flow (like loops and conditions). It helps make asynchronous code more readable and easier to manage.

The generator functions work similarly to async/await but with more explicit control over the execution of effects. You can yield* values from effects and return the final result at the end.

Example

import { Effect } from "effect"
const addServiceCharge = (amount: number) => amount + 1
const applyDiscount = (
total: number,
discountRate: number
): Effect.Effect<number, Error> =>
discountRate === 0
? Effect.fail(new Error("Discount rate cannot be zero"))
: Effect.succeed(total - (total * discountRate) / 100)
const fetchTransactionAmount = Effect.promise(() => Promise.resolve(100))
const fetchDiscountRate = Effect.promise(() => Promise.resolve(5))
export const program = Effect.gen(function* () {
const transactionAmount = yield* fetchTransactionAmount
const discountRate = yield* fetchDiscountRate
const discountedAmount = yield* applyDiscount(
transactionAmount,
discountRate
)
const finalAmount = addServiceCharge(discountedAmount)
return `Final amount to charge: ${finalAmount}`
})

@since2.0.0

gen
(function* () {
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("开始从延迟值获取值的任务")
const
const value: string
value
= yield*
import Deferred
Deferred
.
await<string, string>(self: Deferred.Deferred<string, string>): Effect.Effect<string, string, never>
export await

Retrieves the value of the Deferred, suspending the fiber running the workflow until the result is available.

@since2.0.0

await
(
const deferred: Deferred.Deferred<string, string>
deferred
)
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
("从延迟值获取了值")
return
const value: string
value
})
// 并发运行两个纤程
const
const fiberA: Fiber.RuntimeFiber<boolean, never>
fiberA
= yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fork: <boolean, never, never>(self: Effect.Effect<boolean, never, never>) => Effect.Effect<Fiber.RuntimeFiber<boolean, never>, never, never>

Creates a new fiber to run an effect concurrently.

Details

This function takes an effect and forks it into a separate fiber, allowing it to run concurrently without blocking the original effect. The new fiber starts execution immediately after being created, and the fiber object is returned immediately without waiting for the effect to begin. This is useful when you want to run tasks concurrently while continuing other tasks in the parent fiber.

The forked fiber is attached to the parent fiber's scope. This means that when the parent fiber terminates, the child fiber will also be terminated automatically. This feature, known as "auto supervision," ensures that no fibers are left running unintentionally. If you prefer not to have this auto supervision behavior, you can use

forkDaemon

or

forkIn

.

When to Use

Use this function when you need to run an effect concurrently without blocking the current execution flow. For example, you might use it to launch background tasks or concurrent computations. However, working with fibers can be complex, so before using this function directly, you might want to explore higher-level functions like

raceWith

,

zip

, or others that can manage concurrency for you.

Example

import { Effect } from "effect"
const fib = (n: number): Effect.Effect<number> =>
n < 2
? Effect.succeed(n)
: Effect.zipWith(fib(n - 1), fib(n - 2), (a, b) => a + b)
// ┌─── Effect<RuntimeFiber<number, never>, never, never>
// ▼
const fib10Fiber = Effect.fork(fib(10))

@seeforkWithErrorHandler for a version that allows you to handle errors.

@since2.0.0

fork
(
const taskA: Effect.Effect<boolean, never, never>
taskA
)
const
const fiberB: Fiber.RuntimeFiber<string, string>
fiberB
= yield*
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const fork: <string, string, never>(self: Effect.Effect<string, string, never>) => Effect.Effect<Fiber.RuntimeFiber<string, string>, never, never>

Creates a new fiber to run an effect concurrently.

Details

This function takes an effect and forks it into a separate fiber, allowing it to run concurrently without blocking the original effect. The new fiber starts execution immediately after being created, and the fiber object is returned immediately without waiting for the effect to begin. This is useful when you want to run tasks concurrently while continuing other tasks in the parent fiber.

The forked fiber is attached to the parent fiber's scope. This means that when the parent fiber terminates, the child fiber will also be terminated automatically. This feature, known as "auto supervision," ensures that no fibers are left running unintentionally. If you prefer not to have this auto supervision behavior, you can use

forkDaemon

or

forkIn

.

When to Use

Use this function when you need to run an effect concurrently without blocking the current execution flow. For example, you might use it to launch background tasks or concurrent computations. However, working with fibers can be complex, so before using this function directly, you might want to explore higher-level functions like

raceWith

,

zip

, or others that can manage concurrency for you.

Example

import { Effect } from "effect"
const fib = (n: number): Effect.Effect<number> =>
n < 2
? Effect.succeed(n)
: Effect.zipWith(fib(n - 1), fib(n - 2), (a, b) => a + b)
// ┌─── Effect<RuntimeFiber<number, never>, never, never>
// ▼
const fib10Fiber = Effect.fork(fib(10))

@seeforkWithErrorHandler for a version that allows you to handle errors.

@since2.0.0

fork
(
const taskB: Effect.Effect<string, string, never>
taskB
)
// 等待两个纤程完成
const
const both: [boolean, string]
both
= yield*
import Fiber
Fiber
.
const join: <[boolean, string], string>(self: Fiber.Fiber<[boolean, string], string>) => Effect.Effect<[boolean, string], string, never>

Joins the fiber, which suspends the joining fiber until the result of the fiber has been determined. Attempting to join a fiber that has erred will result in a catchable error. Joining an interrupted fiber will result in an "inner interruption" of this fiber, unlike interruption triggered by another fiber, "inner interruption" can be caught and recovered.

@since2.0.0

join
(
import Fiber
Fiber
.
const zip: <boolean, never, string, string>(self: Fiber.Fiber<boolean, never>, that: Fiber.Fiber<string, string>) => Fiber.Fiber<[boolean, string], string> (+1 overload)

Zips this fiber and the specified fiber together, producing a tuple of their output.

@since2.0.0

zip
(
const fiberA: Fiber.RuntimeFiber<boolean, never>
fiberA
,
const fiberB: Fiber.RuntimeFiber<string, string>
fiberB
))
var console: Console

The console module provides a simple debugging console that is similar to the JavaScript console mechanism provided by web browsers.

The module exports two specific components:

  • A Console class with methods such as console.log(), console.error() and console.warn() that can be used to write to any Node.js stream.
  • A global console instance configured to write to process.stdout and process.stderr. The global console can be used without importing the node:console module.

Warning: The global console object's methods are neither consistently synchronous like the browser APIs they resemble, nor are they consistently asynchronous like all other Node.js streams. See the note on process I/O for more information.

Example using the global console:

console.log('hello world');
// Prints: hello world, to stdout
console.log('hello %s', 'world');
// Prints: hello world, to stdout
console.error(new Error('Whoops, something bad happened'));
// Prints error message and stack trace to stderr:
// Error: Whoops, something bad happened
// at [eval]:5:15
// at Script.runInThisContext (node:vm:132:18)
// at Object.runInThisContext (node:vm:309:38)
// at node:internal/process/execution:77:19
// at [eval]-wrapper:6:22
// at evalScript (node:internal/process/execution:76:60)
// at node:internal/main/eval_string:23:3
const name = 'Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr

Example using the Console class:

const out = getStreamSomehow();
const err = getStreamSomehow();
const myConsole = new console.Console(out, err);
myConsole.log('hello world');
// Prints: hello world, to out
myConsole.log('hello %s', 'world');
// Prints: hello world, to out
myConsole.error(new Error('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
const name = 'Will Robinson';
myConsole.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to err

@seesource

console
.
Console.log(message?: any, ...optionalParams: any[]): void

Prints to stdout with newline. Multiple arguments can be passed, with the first used as the primary message and all additional used as substitution values similar to printf(3) (the arguments are all passed to util.format()).

const count = 5;
console.log('count: %d', count);
// Prints: count: 5, to stdout
console.log('count:', count);
// Prints: count: 5, to stdout

See util.format() for more information.

@sincev0.1.100

log
(
const both: [boolean, string]
both
)
})
import Effect

@since2.0.0

@since2.0.0

@since2.0.0

Effect
.
const runFork: <void, string>(effect: Effect.Effect<void, string, never>, options?: RunForkOptions) => Fiber.RuntimeFiber<void, string>

Runs an effect in the background, returning a fiber that can be observed or interrupted.

Unless you specifically need a Promise or synchronous operation, runFork is a good default choice.

Details

This function is the foundational way to execute an effect in the background. It creates a "fiber," a lightweight, cooperative thread of execution that can be observed (to access its result), interrupted, or joined. Fibers are useful for concurrent programming and allow effects to run independently of the main program flow.

Once the effect is running in a fiber, you can monitor its progress, cancel it if necessary, or retrieve its result when it completes. If the effect fails, the fiber will propagate the failure, which you can observe and handle.

When to Use

Use this function when you need to run an effect in the background, especially if the effect is long-running or performs periodic tasks. It's suitable for tasks that need to run independently but might still need observation or management, like logging, monitoring, or scheduled tasks.

This function is ideal if you don't need the result immediately or if the effect is part of a larger concurrent workflow.

Example (Running an Effect in the Background)

import { Effect, Console, Schedule, Fiber } from "effect"
// ┌─── Effect<number, never, never>
// ▼
const program = Effect.repeat(
Console.log("running..."),
Schedule.spaced("200 millis")
)
// ┌─── RuntimeFiber<number, never>
// ▼
const fiber = Effect.runFork(program)
setTimeout(() => {
Effect.runFork(Fiber.interrupt(fiber))
}, 500)

@since2.0.0

runFork
(
const program: Effect.Effect<void, string, never>
program
)
/*
开始完成延迟值的任务
开始从延迟值获取值的任务
完成延迟值
从延迟值获取了值
[ true, 'hello world' ]
*/