1

I'm trying to write a parallelMap implementation with coroutines. So far I have

suspend fun <T, R> Iterable<T>.parallelMapCoroutine(f: (T) -> R): List<R> =
    coroutineScope {
        map {
            async { f(it) }
        }.map { deferred -> deferred.await() }
    }

Now as I understand it, this can't return until all the async tasks have returned, because I need to await them to get their values? But it feels like I should be able to return a Deferred<List>, like I can with CompletableFutures in Java.

Convert from List<CompletableFuture> to CompletableFuture<List>

Or is there a better way to achieve my aim?

Duncan McGregor
  • 17,665
  • 12
  • 64
  • 118
  • Coroutines were invented specifically, so we don't have to use callbacks or futures, but instead use traditional, sequential code. Why do you prefer to get Deferred instead of just waiting for the result? – broot Nov 23 '22 at 23:33
  • If we can cast this as a suspend function that doesn’t use deferred that would be great. I don’t want to wait for the result so that I can get on with doing other things on this thread – Duncan McGregor Nov 23 '22 at 23:46
  • 1
    Well, your above code already does what you want :-) This is the main point of coroutines - to wait without blocking the thread and keep the code simple. BTW, you can replace `.map { deferred -> deferred.await() }` with `.awaitAll()`. – broot Nov 24 '22 at 00:35
  • TL;DR: It is not possible to convert `List` to `Deferred`. `async { f(it) }` will return a deferred object. Each of these objects will be computed by a coroutine when you seek a `Deferred`, the list has to be computed by a single coroutine. – NewUser Nov 24 '22 at 00:59
  • @NewUser, well, it is possible using `async { listOfDeferreds.awaitAll() }`. It’s just kind of an odd thing to want to do. – Tenfour04 Nov 24 '22 at 03:41
  • @Tenfour04 - `awaitAll` returns the object not deferred as OP asked initially. – NewUser Nov 24 '22 at 11:26
  • I'm probably missing something, but what's the difference between having a `List>` which we can `awaitAll` on, and a Deferred> which can call `await` on? – matt freake Nov 24 '22 at 11:53
  • 1
    @NewUser, yes but if you wrap that in async like I did in my comment, then it returns a Deferred. – Tenfour04 Nov 24 '22 at 13:28
  • Thanks for the useful discussion. I'm just dipping my toes into coroutines concurreny, so its good context for me – Duncan McGregor Nov 25 '22 at 09:04

0 Answers0