Consecutively array map with async

I couldn’t find any helper functions to like Array.mapAsync or something so I wrote my own:

let result = await ([1, 2, 3]->ArrayAsync.iterAsync(_, async v=>{
  // do async stuff
  return v+1
}))
// -> [2, 3, 4]
1 Like

Just a gotcha: neither ReScript nor your JS engine will optimize it. While synchronous recursive functions can be optimized by ReScript into a JS while loop, asynchronous functions can not.

But there are optimizations in V8 and other runtimes to handle await calls in loops.
So you should prefer that instead:

let iterAsyncFor: (array<'a>, 'a => promise<'b>) => promise<array<'b>> = async (
  arr,
  fn,
) => {
  let result = []

  for v in 0 to arr->Array.length - 1 {
    result[v] = await fn(arr->Array.getUnsafe(v))
  }

  result
}
1 Like

Anything wrong with this ?

let mapAsync = (arr, fn) => arr->Array.map(fn)->Promise.all

@gaspard Promise.all runs the promises in parallel, if I’m running db queries or http calls inside them it could have unintended consequences.

As everything can be an expression :heart: I tried for ... in .. to .. async { which didn’t work, so yeah my first attempt was to do recursion, that’s learning :muscle:

Thanks I’ve updated the code and its working well!

1 Like