Repeat
Flow.repeatSync keeps calling a function, yielding the results one-by-one as a generator. This is the synchronous version.
import { repeatSync } from "https://unpkg.com/ixfx/dist/flow.js"
// Five random numbers in an arrayconst results = [...repeatSync(Math.random, { count: 5 })];
// Or in a for-of loop:for (const result of repeat(Math.random, { count: 5 })) { console.log(result);}// Exits after 5 numbers
There’s also an asynchronous version, Flow.repeat .
import { repeat, sleep } from "https://unpkg.com/ixfx/dist/flow.js"
// Some function that doesn't return until 1 secondasync function task() { await sleep(1000); return Math.random();}
// Will print 5 random numbers, one second apart.for await (const result of repeat(task, { count: 5 })) { console.log(result);}
Instead of using for await
you can use JS’s in-built Array.fromAsync
:
const data = await Array.fromAsync(repeat(task, { count: 5}));
repeat
allows you to add delays when looping:
// Wait at least 1 second between each task execution// This will automatically shorten wait periods depending// how long the task takes.for await (const r of repeat(task, { delayMinimum: 1000 }));
// Wait at least 1 second between each task,// regardless of how long the task takesfor await (const r of repeat(task, { delay: 1000 }));
To revisit the earlier example, this will get up to five random numbers, with one second delay between each.
const gen = repeat(Math.random, { delayFixed: 1000, count: 5 });for await (const r of gen) { // 'r' will be a random number}
Advanced
repeat
will stop if its source stops. It will also stop if the source returns undefined. If you want to allow this, pass in allowUndefined: true
as an option.
The options allow you to be notified when the repeat first starts going, or when it is complete:
import { repeat } from "https://unpkg.com/ixfx/dist/flow.js"repeat(gen, { onComplete(withError) { // called when 'repeat' is done. // withError is _true_ if there was an error }, onStart() { // called when repeating starts for the first time }})
It can also stop on the basis of an AbortSignal
:
import { repeat } from "https://unpkg.com/ixfx/dist/flow.js"const ac = new AbortController();repeat(gen, { signal: ac.signal});
// Somewhere else:ac.abort(); // Cause `repeat` to exit