Deferred.ts
Deferred.ts overview
Section titled “Deferred.ts overview”One-time coordination cells for Effect programs. A Deferred<A, E> starts
empty, can be completed exactly once with a success, failure, defect, or
interruption, and lets any number of fibers wait for that result. Awaiting a
Deferred suspends the fiber instead of blocking an operating-system thread,
and every waiter observes the same completion.
Since v2.0.0
Exports Grouped by Category
Section titled “Exports Grouped by Category”Synchronization Utilities
Section titled “Synchronization Utilities”Runs an Effect and attempts to complete a Deferred with the effect’s
result.
When to use
Use to pipe an effect result into a Deferred while preserving success,
failure, defects, and interruption.
Details
If the effect succeeds, fails, dies, or is interrupted, that result is used
as the attempted completion. The returned effect cannot fail; it succeeds
with true if it completed the Deferred, or false if the Deferred was
already completed.
Example (Completing a Deferred from an effect result)
import { Deferred, Effect } from "effect"
// Define an effect that succeedsconst successEffect = Effect.succeed(42)
const program = Effect.gen(function* () { // Create a deferred const deferred = yield* Deferred.make<number, string>()
// Complete the deferred using the successEffect const isCompleted = yield* Deferred.into(successEffect, deferred)
// Access the value of the deferred const value = yield* Deferred.await(deferred) console.log(value)
return isCompleted})
Effect.runPromise(program).then(console.log)// Output:// 42// trueSignature
declare const into: { <A, E>(deferred: Deferred<A, E>): <R>(self: Effect<A, E, R>) => Effect<boolean, never, R> <A, E, R>(self: Effect<A, E, R>, deferred: Deferred<A, E>): Effect<boolean, never, R>}Since v4.0.0
completion
Section titled “completion”complete
Section titled “complete”Runs the supplied Effect and attempts to complete the Deferred with its
memoized result.
When to use
Use when completing a Deferred should run an effect once and share its
result with all awaiters.
Details
The returned effect succeeds with true when this call completed the
Deferred, or false if it was already completed.
Example (Completing a Deferred from an effect)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const completed = yield* Deferred.complete(deferred, Effect.succeed(42)) console.log(completed) // true
const value = yield* Deferred.await(deferred) console.log(value) // 42})See
completeWithfor storing an effect directly without memoizing its result
Signature
declare const complete: { <A, E, R>(effect: Effect<A, E, R>): (self: Deferred<A, E>) => Effect<boolean, never, R> <A, E, R>(self: Deferred<A, E>, effect: Effect<A, E, R>): Effect<boolean, never, R>}Since v2.0.0
completeWith
Section titled “completeWith”Attempts to complete the Deferred with the specified effect directly.
When to use
Use to store an already environment-free effect as the completion without running it during completion.
Details
The returned effect succeeds with true when this call completed the
Deferred, or false if it was already completed.
Gotchas
The supplied effect is not memoized by completeWith; each awaiter may run
the stored effect independently.
Example (Completing a Deferred with an effect)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const completed = yield* Deferred.completeWith(deferred, Effect.succeed(42)) console.log(completed) // true
const value = yield* Deferred.await(deferred) console.log(value) // 42})See
completefor running an effect once and sharing its resultdonefor completing from an already computedExit
Signature
declare const completeWith: { <A, E>(effect: Effect<A, E>): (self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, effect: Effect<A, E>): Effect<boolean>}Since v2.0.0
Attempts to complete the Deferred with a defect.
When to use
Use to complete a Deferred with an unexpected defect.
Details
Fibers waiting on the Deferred die with that defect only if this call
completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Killing a Deferred with a defect)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const success = yield* Deferred.die(deferred, new Error("Something went wrong")) console.log(success) // true})Signature
declare const die: { (defect: unknown): <A, E>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, defect: unknown): Effect<boolean>}Since v2.0.0
dieSync
Section titled “dieSync”Computes a defect when the returned effect is run, then attempts to complete
the Deferred with that defect.
When to use
Use to lazily compute an unexpected defect when the completion effect runs.
Details
Fibers waiting on the Deferred die with the computed defect only if this
call completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Killing a Deferred with a lazy defect)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const success = yield* Deferred.dieSync(deferred, () => new Error("Lazy error")) console.log(success) // true})Signature
declare const dieSync: { (evaluate: LazyArg<unknown>): <A, E>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, evaluate: LazyArg<unknown>): Effect<boolean>}Since v2.0.0
Completes the Deferred with the specified Exit value, which will be
propagated to all fibers waiting on the value of the Deferred.
When to use
Use to complete a Deferred from an already computed Exit.
Details
The returned effect succeeds with true when this call completed the
Deferred, or false if it was already completed.
Example (Completing a Deferred with an Exit)
import { Deferred, Effect, Exit } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() yield* Deferred.done(deferred, Exit.succeed(42))
const value = yield* Deferred.await(deferred) console.log(value) // 42})See
completefor completing from an effect and memoizing its resultcompleteWithfor storing an effect directlysucceedfor completing with a success valuefailCausefor completing with a failure cause
Signature
declare const done: { <A, E>(exit: Exit.Exit<A, E>): (self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, exit: Exit.Exit<A, E>): Effect<boolean>}Since v2.0.0
Attempts to complete the Deferred with the specified error.
When to use
Use to complete a Deferred with a typed failure value.
Details
Fibers waiting on the Deferred fail with that error only if this call
completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Failing a Deferred with an error)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number, string>() const success = yield* Deferred.fail(deferred, "Operation failed") console.log(success) // true})Signature
declare const fail: { <E>(error: E): <A>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, error: E): Effect<boolean>}Since v2.0.0
failCause
Section titled “failCause”Attempts to complete the Deferred with the specified Cause.
When to use
Use to complete a Deferred with a full failure cause.
Details
Fibers waiting on the Deferred observe that cause only if this call
completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Failing a Deferred with a Cause)
import { Cause, Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number, string>() const success = yield* Deferred.failCause(deferred, Cause.fail("Operation failed")) console.log(success) // true})Signature
declare const failCause: { <E>(cause: Cause.Cause<E>): <A>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, cause: Cause.Cause<E>): Effect<boolean>}Since v2.0.0
failCauseSync
Section titled “failCauseSync”Computes a Cause when the returned effect is run, then attempts to
complete the Deferred with that cause.
When to use
Use to lazily compute a full failure cause when the Deferred completion
effect runs.
Details
Fibers waiting on the Deferred observe the computed cause only if this
call completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Failing a Deferred with a lazy Cause)
import { Cause, Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number, string>() const success = yield* Deferred.failCauseSync(deferred, () => Cause.fail("Lazy error")) console.log(success) // true})Signature
declare const failCauseSync: { <E>(evaluate: LazyArg<Cause.Cause<E>>): <A>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, evaluate: LazyArg<Cause.Cause<E>>): Effect<boolean>}Since v2.0.0
failSync
Section titled “failSync”Computes an error when the returned effect is run, then attempts to complete
the Deferred with that error.
When to use
Use to lazily compute a typed failure value when the Deferred completion
effect runs.
Details
Fibers waiting on the Deferred fail with the computed error only if this
call completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Failing a Deferred with a lazy error)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number, string>() const success = yield* Deferred.failSync(deferred, () => "Lazy error") console.log(success) // true})Signature
declare const failSync: { <E>(evaluate: LazyArg<E>): <A>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, evaluate: LazyArg<E>): Effect<boolean>}Since v2.0.0
interrupt
Section titled “interrupt”Attempts to complete the Deferred with interruption by the current fiber.
When to use
Use to complete a Deferred as interrupted by the current fiber.
Details
Fibers waiting on the Deferred are interrupted with the current fiber id
only if this call completes it. The returned effect succeeds with true
when this call completed the Deferred, or false if it was already
completed.
Example (Interrupting a Deferred)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const success = yield* Deferred.interrupt(deferred) console.log(success) // true})Signature
declare const interrupt: <A, E>(self: Deferred<A, E>) => Effect<boolean>Since v2.0.0
interruptWith
Section titled “interruptWith”Attempts to complete the Deferred with interruption by the specified
FiberId.
When to use
Use to complete a Deferred as interrupted by a specific fiber id.
Details
Fibers waiting on the Deferred are interrupted with that fiber id only if
this call completes it. The returned effect succeeds with true when this
call completed the Deferred, or false if it was already completed.
Example (Interrupting a Deferred with a fiber id)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const success = yield* Deferred.interruptWith(deferred, 42) console.log(success) // true})Signature
declare const interruptWith: { (fiberId: number): <A, E>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, fiberId: number): Effect<boolean>}Since v2.0.0
succeed
Section titled “succeed”Attempts to complete the Deferred with the specified value.
When to use
Use to complete a Deferred with a successful value.
Details
Fibers waiting on the Deferred receive the value only if this call
completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Completing a Deferred with a value)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() yield* Deferred.succeed(deferred, 42)
const value = yield* Deferred.await(deferred) console.log(value) // 42})Signature
declare const succeed: { <A>(value: A): <E>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, value: A): Effect<boolean>}Since v2.0.0
Computes a value when the returned effect is run, then attempts to complete
the Deferred with that value.
When to use
Use to lazily compute a successful value when the Deferred completion
effect runs.
Details
Fibers waiting on the Deferred receive the computed value only if this call
completes it. The returned effect succeeds with true when this call
completed the Deferred, or false if it was already completed.
Example (Completing a Deferred with a lazy value)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() yield* Deferred.sync(deferred, () => 42)
const value = yield* Deferred.await(deferred) console.log(value) // 42})Signature
declare const sync: { <A>(evaluate: LazyArg<A>): <E>(self: Deferred<A, E>) => Effect<boolean> <A, E>(self: Deferred<A, E>, evaluate: LazyArg<A>): Effect<boolean>}Since v2.0.0
constructors
Section titled “constructors”Creates a new Deferred.
When to use
Use to allocate an empty Deferred inside an Effect workflow.
Example (Creating a Deferred)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() yield* Deferred.succeed(deferred, 42) const value = yield* Deferred.await(deferred) console.log(value) // 42})Signature
declare const make: <A, E = never>() => Effect<Deferred<A, E>>Since v2.0.0
getters
Section titled “getters”Retrieves the value of the Deferred, suspending the fiber running the
workflow until the result is available.
When to use
Use to wait for a Deferred to be completed and resume with its success,
failure, defect, or interruption.
Details
Awaiters observe the completion effect stored in the Deferred.
Example (Awaiting a Deferred value)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() yield* Deferred.succeed(deferred, 42)
const value = yield* Deferred.await(deferred) console.log(value) // 42})See
completefor completing from an effect and memoizing its resultcompleteWithfor completing with an effect directly
Signature
declare const await: <A, E>(self: Deferred<A, E>) => Effect<A, E>Since v2.0.0
isDone
Section titled “isDone”Returns true if this Deferred has already been completed with a value or
an error, false otherwise.
When to use
Use to check completion status inside an Effect workflow.
Example (Checking Deferred completion)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const beforeCompletion = yield* Deferred.isDone(deferred) console.log(beforeCompletion) // false
yield* Deferred.succeed(deferred, 42) const afterCompletion = yield* Deferred.isDone(deferred) console.log(afterCompletion) // true})Signature
declare const isDone: <A, E>(self: Deferred<A, E>) => Effect<boolean>Since v2.0.0
isDoneUnsafe
Section titled “isDoneUnsafe”Returns whether this Deferred has already been completed synchronously.
When to use
Use to check Deferred completion synchronously in code that cannot return
an Effect, such as low-level integration code.
See
isDonefor checking completion insideEffectpollfor reading the completed effect when available
Signature
declare const isDoneUnsafe: <A, E>(self: Deferred<A, E>) => booleanSince v4.0.0
Returns the current completion effect as an Option. This returns
Option.some(effect) when the Deferred is completed, Option.none()
otherwise.
When to use
Use to inspect whether a Deferred is already completed and retrieve its
stored completion effect when available.
Example (Polling Deferred completion)
import { Deferred, Effect } from "effect"
const program = Effect.gen(function* () { const deferred = yield* Deferred.make<number>() const beforeCompletion = yield* Deferred.poll(deferred) console.log(beforeCompletion._tag === "None") // true
yield* Deferred.succeed(deferred, 42) const afterCompletion = yield* Deferred.poll(deferred) console.log(afterCompletion._tag === "Some") // true})Signature
declare const poll: <A, E>(self: Deferred<A, E>) => Effect<Option.Option<Effect<A, E>>>Since v2.0.0
guards
Section titled “guards”isDeferred
Section titled “isDeferred”Checks whether a value is a Deferred.
When to use
Use to validate unknown values at runtime boundaries before treating them as
Deferred values.
Signature
declare const isDeferred: <A, E>(u: unknown) => u is Deferred<A, E>Since v4.0.0
models
Section titled “models”Deferred (interface)
Section titled “Deferred (interface)”A Deferred represents an asynchronous variable that can be set exactly
once, with the ability for an arbitrary number of fibers to suspend (by
calling Deferred.await) and automatically resume when the variable is set.
When to use
Use to coordinate multiple fibers around a value or failure that will be supplied exactly once.
Example (Creating a Deferred for inter-fiber communication)
import { Deferred, Effect, Fiber } from "effect"
// Create and use a Deferred for inter-fiber communicationconst program = Effect.gen(function* () { // Create a Deferred that will hold a string value const deferred: Deferred.Deferred<string> = yield* Deferred.make<string>()
// Fork a fiber that will set the deferred value const producer = yield* Effect.forkChild( Effect.gen(function* () { yield* Effect.sleep("100 millis") yield* Deferred.succeed(deferred, "Hello, World!") }) )
// Fork a fiber that will await the deferred value const consumer = yield* Effect.forkChild( Effect.gen(function* () { const value = yield* Deferred.await(deferred) console.log("Received:", value) return value }) )
// Wait for both fibers to complete yield* Fiber.join(producer) const result = yield* Fiber.join(consumer) return result})Signature
export interface Deferred<in out A, in out E = never> extends Deferred.Variance<A, E>, Pipeable { effect?: Effect<A, E> resumes?: Array<(effect: Effect<A, E>) => void> | undefined}Since v2.0.0
unsafe
Section titled “unsafe”doneUnsafe
Section titled “doneUnsafe”Attempts to complete the Deferred synchronously with the specified
completion effect.
When to use
Use to complete a Deferred synchronously in low-level code that already has
the completion effect.
Details
This mutates the Deferred directly and should be reserved for low-level
code; prefer the effectful completion APIs when possible. Returns true if
this call completed the Deferred, or false if it was already completed.
Example (Completing a Deferred unsafely)
import { Deferred, Effect } from "effect"
const deferred = Deferred.makeUnsafe<number>()const success = Deferred.doneUnsafe(deferred, Effect.succeed(42))console.log(success) // trueSignature
declare const doneUnsafe: <A, E>(self: Deferred<A, E>, effect: Effect<A, E>) => booleanSince v4.0.0
makeUnsafe
Section titled “makeUnsafe”Creates an empty Deferred synchronously outside the Effect runtime.
When to use
Use to allocate a Deferred synchronously when direct allocation outside
Effect is required.
Example (Creating a Deferred unsafely)
import { Deferred } from "effect"
const deferred = Deferred.makeUnsafe<number>()console.log(deferred)Signature
declare const makeUnsafe: <A, E = never>() => Deferred<A, E>Since v4.0.0
Deferred (namespace)
Section titled “Deferred (namespace)”Companion namespace containing type-level metadata for Deferred.
When to use
Use to reference type-level metadata associated with Deferred.
Since v2.0.0
Variance (interface)
Section titled “Variance (interface)”Type-level variance marker for the value and error channels of Deferred.
When to use
Use to carry the value and error type parameters for Deferred in Effect’s
type machinery.
Details
This interface is part of the public type structure and is not intended to be constructed directly.
Signature
export interface Variance<in out A, in out E> { readonly [TypeId]: { readonly _A: Types.Invariant<A> readonly _E: Types.Invariant<E> }}Since v2.0.0