Currently I'm using Effect-Ts to perform multiple operations (promises) with some concurrency level using Effect.all
.
Here the very basic code:
async function method<R>(
fn: (() => Promise<R>)[],
concurrency: number,
) {
const tasks = fn.map(c =>
Effect.promise(c)
)
let effect = Effect.all(tasks, {
concurrency: concurrency,
})
const results = await Effect.runPromise(effect)
return results
}
I want to track the process and have a sort of progress bar like this:
Progress: 1/100
Progress: 2/100
...
Progress: 100/100
I've tried (and read) multiple stuff but I haven't been able to achieve what I wanted.
What is the most appropriate way to handle this need?
Many thx.
Ok here's how I've solved it.
I'm not sure if it can be considered pure functional programming since I'm modifying the progress
variable but it worked for my need.
*Note that I've avoided printing logs for every Promise resolution instead I've used ticks
to limit the "noise"
const options = {
totalTicks: 15,
onNewTicks: (index: number, total: number) => console.log(`Fetching chunk ${index + 1} of ${total} (${Math.floor((index / total) * 100)}%)`),
concurrency: 5
}
const executeTasks = <A>(
tasks: ReadonlyArray<Task<A>>
) => {
let progress = 0
let ticks = tasks.length / options.totalTicks
let currentTick = 0
const effects = tasks.map(c =>
pipe(
Effect.promise(c),
Effect.tap(() => {
progress++
if (progress / ticks > currentTick) {
return options.onNewTicks(currentTick++, options.totalTicks)
}
}),
),
)
return Effect.all(effects, {
concurrency: options.concurrency,
})
}