Skip to content

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 array
const 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 second
async 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 takes
for 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