Repetition
Repetition is a common requirement when working with effects in software development. It allows us to perform an effect multiple times according to a specific repetition policy.
Repeat policies are used in the following functions:
repeat
: Repeats an effect until the schedule is done.repeatOrElse
: Repeats an effect until the schedule is done, with a fallback for errors.
Scheduled recurrences are in addition to the first execution, so that
repeat(effect, Schedule.once)
yields an effect that executes effect
, and
then if that succeeds, executes effect
an additional time.
repeat
The basic syntax of repeat
is as follows:
Effect.repeat(action, policy)
Example
import { Effect, Schedule, Console } from "effect"
const action = Console.log("success")
const policy = Schedule.addDelay(
Schedule.recurs(2), // Repeat for a maximum of 2 times
() => "100 millis" // Add a delay of 100 milliseconds between repetitions
)
const program = Effect.repeat(action, policy)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
/*
Output:
success
success
success
repetitions: 2
*/
repeatOrElse
There is another version of repeat
that helps us to have a fallback strategy in case of erros,
if something goes wrong we can handle that by using the Effect.repeatOrElse
function,
which helps up to add an orElse
callback that will run in case of repetition failure.
The basic syntax of repeatOrElse
is as follows:
Effect.repeatOrElse(action, policy, fallback)
Example
import { Effect, Schedule } from "effect"
let count = 0
// Define an async effect that simulates an action with possible failures
const action = Effect.async<never, Error, string>((resume) => {
if (count > 1) {
console.log("failure")
resume(Effect.fail(new Error()))
} else {
count++
console.log("success")
resume(Effect.succeed("yay!"))
}
})
const policy = Schedule.addDelay(
Schedule.recurs(2), // Repeat for a maximum of 2 times
() => "100 millis" // Add a delay of 100 milliseconds between repetitions
)
const program = Effect.repeatOrElse(action, policy, () =>
Effect.sync(() => {
console.log("orElse")
return count - 1
})
)
Effect.runPromise(program).then((n) => console.log(`repetitions: ${n}`))
/*
Output:
success
success
failure
orElse
repetitions: 1
*/