# Java 9 Flow API: mapping asynchronously

DevFeed: [Java 9 Flow API: mapping asynchronously](<https://devfeed.tech/articles/java-9-flow-api-mapping-asynchronously-24809.md>)

Original publisher: [Read original article](<https://akarnokd.blogspot.com/2017/09/java-9-flow-api-mapping-asynchronously.html>)

Author: David Karnok (noreply@blogger.com)

Published: 2017-09-07T14:00:00Z

Content type: tutorial

Language: en

Sources: [Akarnokd - Advanced RxJava](<https://devfeed.tech/sources/akarnokd-advanced-rxjava.md>)

Topics: [Java](<https://devfeed.tech/topics/java.md>), [Java 9](<https://devfeed.tech/topics/java-9.md>), [reactive](<https://devfeed.tech/topics/reactive.md>), [Concurrency](<https://devfeed.tech/topics/concurrency.md>), [implementation](<https://devfeed.tech/topics/implementation.md>), [API](<https://devfeed.tech/topics/api.md>)

Tags: [api](<https://devfeed.tech/tags/api.md>), [asynchronous](<https://devfeed.tech/tags/asynchronous.md>), [concatmap](<https://devfeed.tech/tags/concatmap.md>), [flow](<https://devfeed.tech/tags/flow.md>), [flow-api](<https://devfeed.tech/tags/flow-api.md>), [java](<https://devfeed.tech/tags/java.md>), [java-9](<https://devfeed.tech/tags/java-9.md>), [jdk](<https://devfeed.tech/tags/jdk.md>), [map](<https://devfeed.tech/tags/map.md>), [mapping](<https://devfeed.tech/tags/mapping.md>), [reactive](<https://devfeed.tech/tags/reactive.md>), [rxjava](<https://devfeed.tech/tags/rxjava.md>), [varhandle](<https://devfeed.tech/tags/varhandle.md>)

## AI overview

This tutorial presents the mapWhen operator for asynchronously mapping Java 9 Flow.Publisher values. It explains how the operator supports one-at-a-time mapping, limits inner publishers to one element, and can combine the original and mapped values.

## Source excerpt

Introduction There are cases where mapping an upstream value of type T has to be mapped to type U , one-for-one, but the mapping process itself involves asynchronous work. With RxJava, this is a de-facto use case for concatMap, concatMapEager and flatMap, depending on the concurrency expectations about the mapping itself (i.e., one at a time, multiple at once but in-order and arbitrary order respectively). Let's assume we don't want to run multiple concurrent mapping thus concatMap would suffice. We can (and will in a future post) write that operator, but we should face two additional challenges: the standard Java 9 Flow API has no notion of 0..1 reactive type so we have to restrict the inner Flow.Publisher to at most one element (take(1)); and we'd sometimes zip the original and the mapped result into a third type R. These requirements warrant their own custom operator, enter mapWhen(). The mapWhen operator I must admit, the name comes from Reactor-Core after they picked my implementation named mapAsync() from RxJava 2 Extensions. It certainly matches the naming of other operators, such retryWhen(), but arguably the function parameter signature is different (i.e., not a Publisher -> Publisher transformation): public static <T, U> Flow.Publisher<U> mapWhen(Flow.Publisher<T> source, Function<? super T, ? extends Flow.Publisher<U>> mapper) { return mapWhen(source, mapper, (t, u) -> u); } public static <T, U, R> Flow.Publisher<R> mapWhen(Flow.Publisher<T> source, Function<? super T, ? extends Flow.Publisher<U>> mapper, BiFunction<? super T, ? super U, ? extend R> combiner ) { return new FlowMapWhen<>(source, mapper, combiner); } One would think that supporting the combiner case with the same operator implementation adds unreasonable overhead. We'll see later that this is not the case because both the original and mapped value will be available in a way that makes application (t, u) -> u bi-function a trivial, and when JIT-ed, a fall-through case. I'll omit the outer Fl