These examples demonstrate different approaches to handling timeouts, retries, and periodic execution using Effect. Each scenario ensures that the application remains responsive and resilient to failures while adapting dynamically to various conditions.
Handling Timeouts and Retries for API Calls
When calling third-party APIs, it is often necessary to enforce timeouts and implement retry mechanisms to handle transient failures. In this example, the API call retries up to two times in case of failure and will be interrupted if it takes longer than 4 seconds.
Creates an Effect that represents an asynchronous computation that might fail.
When to Use
In situations where you need to perform asynchronous operations that might fail, such as fetching data from an API, you can use the tryPromise constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors.
Error Handling
There are two ways to handle errors with tryPromise:
If you don't provide a catch function, the error is caught and the effect fails with an UnknownException.
If you provide a catch function, the error is caught and the catch function maps it to an error of type E.
Interruptions
An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API.
Example (Fetching a TODO Item)
import { Effect } from"effect"
constgetTodo= (id:number) =>
// Will catch any errors and propagate them as UnknownException
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then((
res: Response
res) => {
7
if (!
res: Response
res.
Response.ok: boolean
ok) {
8
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Retries a failing effect based on a defined retry policy.
Details
The Effect.retry function takes an effect and a
Schedule
policy, and will automatically retry the effect if it fails, following the rules of the policy.
If the effect ultimately succeeds, the result will be returned.
If the maximum retries are exhausted and the effect still fails, the failure is propagated.
When to Use
This can be useful when dealing with intermittent failures, such as network issues or temporary resource unavailability. By defining a retry policy, you can control the number of retries, the delay between them, and when to stop retrying.
@see ― retryOrElse for a version that allows you to run a fallback.
@see ― repeat if your retry condition is based on successful outcomes rather than errors.
@since ― 2.0.0
retry({
times: number
times: 2 }),
21
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect.
consttimeout: (duration:DurationInput) => <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<A, E|TimeoutException, R> (+1overload)
Adds a time limit to an effect, triggering a timeout if the effect exceeds the duration.
Details
This function allows you to enforce a time limit on the execution of an effect. If the effect does not complete within the given duration, it fails with a TimeoutException. This is useful for preventing tasks from hanging indefinitely, especially in scenarios where responsiveness or resource limits are critical.
The returned effect will either:
Succeed with the original effect's result if it completes within the specified duration.
Fail with a TimeoutException if the time limit is exceeded.
Example
import { Effect } from"effect"
consttask= Effect.gen(function* () {
console.log("Start processing...")
yield* Effect.sleep("2 seconds") // Simulates a delay in processing
console.log("Processing complete.")
return"Result"
})
// Output will show a TimeoutException as the task takes longer
Handles all errors in an effect by providing a fallback effect.
Details
This function catches any errors that may occur during the execution of an effect and allows you to handle them by specifying a fallback effect. This ensures that the program continues without failing by recovering from errors using the provided fallback logic.
Note: This function only handles recoverable errors. It will not recover from unrecoverable defects.
Example (Providing Recovery Logic for Recoverable Errors)
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.
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.
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.
Sometimes, retries should only happen for certain error conditions. For example, if an API call fails with a 401 Unauthorized response, retrying might make sense, while a 404 Not Found error should not trigger a retry.
Creates an Effect that represents an asynchronous computation that might fail.
When to Use
In situations where you need to perform asynchronous operations that might fail, such as fetching data from an API, you can use the tryPromise constructor. This constructor is designed to handle operations that could throw exceptions by capturing those exceptions and transforming them into manageable errors.
Error Handling
There are two ways to handle errors with tryPromise:
If you don't provide a catch function, the error is caught and the effect fails with an UnknownException.
If you provide a catch function, the error is caught and the catch function maps it to an error of type E.
Interruptions
An optional AbortSignal can be provided to allow for interruption of the wrapped Promise API.
Example (Fetching a TODO Item)
import { Effect } from"effect"
constgetTodo= (id:number) =>
// Will catch any errors and propagate them as UnknownException
Attaches callbacks for the resolution and/or rejection of the Promise.
@param ― onfulfilled The callback to execute when the Promise is resolved.
@param ― onrejected The callback to execute when the Promise is rejected.
@returns ― A Promise for the completion of which ever callback is executed.
then((
res: Response
res) => {
14
if (!
res: Response
res.
Response.ok: boolean
ok) {
15
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Retries a failing effect based on a defined retry policy.
Details
The Effect.retry function takes an effect and a
Schedule
policy, and will automatically retry the effect if it fails, following the rules of the policy.
If the effect ultimately succeeds, the result will be returned.
If the maximum retries are exhausted and the effect still fails, the failure is propagated.
When to Use
This can be useful when dealing with intermittent failures, such as network issues or temporary resource unavailability. By defining a retry policy, you can control the number of retries, the delay between them, and when to stop retrying.
Handles all errors in an effect by providing a fallback effect.
Details
This function catches any errors that may occur during the execution of an effect and allows you to handle them by specifying a fallback effect. This ensures that the program continues without failing by recovering from errors using the provided fallback logic.
Note: This function only handles recoverable errors. It will not recover from unrecoverable defects.
Example (Providing Recovery Logic for Recoverable Errors)
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.
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.
Retrying with Dynamic Delays Based on Error Information
Some API errors, such as 429 Too Many Requests, include a Retry-After header that specifies how long to wait before retrying. Instead of using a fixed delay, we can dynamically adjust the retry interval based on this value.
Example (Using the Retry-After Header for Retry Delays)
This approach ensures that the retry delay adapts dynamically to the server’s response, preventing unnecessary retries while respecting the provided Retry-After value.
1
import {
import Duration
Duration,
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect,
import Schedule
Schedule,
import Data
Data } from"effect"
2
3
// Custom error class representing a "Too Many Requests" response
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.
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Creates an Effect that represents a recoverable error.
When to Use
Use this function to explicitly signal an error in an Effect. The error will keep propagating unless it is handled. You can handle the error with functions like
catchAll
or
catchTag
.
Example (Creating a Failed Effect)
import { Effect } from"effect"
// ┌─── Effect<never, Error, never>
// ▼
constfailure= Effect.fail(
newError("Operation failed due to network error")
)
@see ― succeed to create an effect that represents a successful value.
@since ― 2.0.0
fail(new
constructor TooManyRequestsError<{
readonlyretryAfter:number;
}>(args: {
readonlyretryAfter:number;
}):TooManyRequestsError
TooManyRequestsError({
retryAfter: number
retryAfter }))
16
}
17
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(newError('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
constname='Will Robinson';
console.warn(`Danger ${name}! Danger!`);
// Prints: Danger Will Robinson! Danger!, to stderr
Example using the Console class:
constout=getStreamSomehow();
consterr=getStreamSomehow();
constmyConsole=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(newError('Whoops, something bad happened'));
// Prints: [Error: Whoops, something bad happened], to err
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()).
Creates a schedule that always recurs, passing inputs directly as outputs.
Details
This schedule runs indefinitely, returning each input value as its output without modification. It effectively acts as a pass-through that simply echoes its input values at each step.
constaddDelay: <TooManyRequestsError>(f: (out:TooManyRequestsError) =>Duration.DurationInput) => <In, R>(self:Schedule.Schedule<TooManyRequestsError, In, R>) =>Schedule.Schedule<TooManyRequestsError, In, R> (+1overload)
Adds a delay to every interval in a schedule.
Details
This function modifies a given schedule by applying an additional delay to every interval it defines. The delay is determined by the provided function, which takes the schedule's output and returns a delay duration.
@see ― addDelayEffect If you need to compute the delay using an effectful function.
@since ― 2.0.0
addDelay((
error: TooManyRequestsError
error) =>
24
error: TooManyRequestsError
error.
_tag: "TooManyRequestsError"
_tag==="TooManyRequestsError"
25
?// Wait for the specified retry-after duration
26
import Duration
Duration.
constmillis: (millis:number) =>Duration.Duration
@since ― 2.0.0
millis(
error: TooManyRequestsError
error.
retryAfter: number
retryAfter)
27
:
import Duration
Duration.
constzero:Duration.Duration
@since ― 2.0.0
zero
28
),
29
// Limit retries to 5 attempts
30
import Schedule
Schedule.
constintersect: <number, unknown, never>(that:Schedule.Schedule<number, unknown, never>) => <Out, In, R>(self:Schedule.Schedule<Out, In, R>) =>Schedule.Schedule<[Out, number], In, R> (+1overload)
Combines two schedules, continuing only if both schedules want to continue, using the longer delay.
Details
This function takes two schedules and creates a new schedule that only continues execution if both schedules allow it. The interval between recurrences is determined by the longer delay between the two schedules.
The output of the resulting schedule is a tuple containing the outputs of both schedules. The input type is the intersection of both schedules' input types.
This is useful when coordinating multiple scheduling conditions where execution should proceed only when both schedules permit it.
@see ― intersectWith If you need to use a custom merge function.
A schedule that recurs a fixed number of times before terminating.
Details
This schedule will continue executing until it has been stepped n times, after which it will stop. The output of the schedule is the current count of recurrences.
Retries a failing effect based on a defined retry policy.
Details
The Effect.retry function takes an effect and a
Schedule
policy, and will automatically retry the effect if it fails, following the rules of the policy.
If the effect ultimately succeeds, the result will be returned.
If the maximum retries are exhausted and the effect still fails, the failure is propagated.
When to Use
This can be useful when dealing with intermittent failures, such as network issues or temporary resource unavailability. By defining a retry policy, you can control the number of retries, the delay between them, and when to stop retrying.
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.
Running Periodic Tasks Until Another Task Completes
There are cases where we need to repeatedly perform an action at fixed intervals until another longer-running task finishes. This pattern is common in polling mechanisms or periodic logging.
Example (Running a Scheduled Task Until Completion)
1
import {
import Effect
@since ― 2.0.0
@since ― 2.0.0
@since ― 2.0.0
Effect,
import Console
Console,
import Schedule
Schedule } from"effect"
2
3
// Define a long-running effect
4
// (e.g., a task that takes 5 seconds to complete)
constdelay: (duration:DurationInput) => <A, E, R>(self:Effect.Effect<A, E, R>) =>Effect.Effect<A, E, R> (+1overload)
Delays the execution of an effect by a specified Duration.
**Details
This function postpones the execution of the provided effect by the specified duration. The duration can be provided in various formats supported by the Duration module.
Internally, this function does not block the thread; instead, it uses an efficient, non-blocking mechanism to introduce the delay.
Creates a schedule that recurs at a fixed interval.
Details
This schedule executes at regular, evenly spaced intervals, returning the number of times it has run so far. If the action being executed takes longer than the interval, the next execution will happen immediately to prevent "pile-ups," ensuring that the schedule remains consistent without overlapping executions.
Races two effects and returns the result of the first successful one.
Details
This function takes two effects and runs them concurrently. The first effect that successfully completes will determine the result of the race, and the other effect will be interrupted.
If neither effect succeeds, the function will fail with a Cause containing all the errors.
When to Use
This is useful when you want to run two effects concurrently, but only care about the first one to succeed. It is commonly used in cases like timeouts, retries, or when you want to optimize for the faster response without worrying about the other effect.
Handling Success or Failure with Either
If you want to handle the result of whichever task completes first, whether it succeeds or fails, you can use the Effect.either function. This function wraps the result in an Either type, allowing you to see if the result was a success (Right) or a failure (Left).
Repeats an effect based on a specified schedule or until the first failure.
Details
This function executes an effect repeatedly according to the given schedule. Each repetition occurs after the initial execution of the effect, meaning that the schedule determines the number of additional repetitions. For example, using Schedule.once will result in the effect being executed twice (once initially and once as part of the repetition).
If the effect succeeds, it is repeated according to the schedule. If it fails, the repetition stops immediately, and the failure is returned.
The schedule can also specify delays between repetitions, making it useful for tasks like retrying operations with backoff, periodic execution, or performing a series of dependent actions.
You can combine schedules for more advanced repetition logic, such as adding delays, limiting recursions, or dynamically adjusting based on the outcome of each execution.
Executes an effect and returns the result as a Promise.
Details
This function runs an effect and converts its result into a Promise. If the effect succeeds, the Promise will resolve with the successful result. If the effect fails, the Promise will reject with an error, which includes the failure details of the effect.
The optional options parameter allows you to pass an AbortSignal for cancellation, enabling more fine-grained control over asynchronous tasks.
When to Use
Use this function when you need to execute an effect and work with its result in a promise-based system, such as when integrating with third-party libraries that expect Promise results.
Example (Running a Successful Effect as a Promise)