src/main/java/io/reactivex/Flowable.java
@CheckReturnValue
    @NonNull
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerSupport.NONE)
    public final <R> Flowable<R> flatMap(Function<? super T, ? extends Publisher<? extends R>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        ObjectHelper.verifyPositive(maxConcurrency, "maxConcurrency");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        if (this instanceof ScalarCallable) {
            @SuppressWarnings("unchecked")
            T v = ((ScalarCallable<T>)this).call();
            if (v == null) {
                return empty();
            }
            return FlowableScalarXMap.scalarXMap(v, mapper);
        }
        return RxJavaPlugins.onAssembly(new FlowableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
    }
@CheckReturnValue
    @NonNull
    @BackpressureSupport(BackpressureKind.FULL)
    @SchedulerSupport(SchedulerSupport.NONE)
    public final <R> Flowable<R> flatMap(Function<? super T, ? extends Publisher<? extends R>> mapper,
            boolean delayErrors, int maxConcurrency, int bufferSize) {
        ObjectHelper.requireNonNull(mapper, "mapper is null");
        ObjectHelper.verifyPositive(maxConcurrency, "maxConcurrency");
        ObjectHelper.verifyPositive(bufferSize, "bufferSize");
        if (this instanceof ScalarCallable) {
            @SuppressWarnings("unchecked")
            T v = ((ScalarCallable<T>)this).call();
            if (v == null) {
                return empty();
            }
            return FlowableScalarXMap.scalarXMap(v, mapper);
        }
        return RxJavaPlugins.onAssembly(new FlowableFlatMap<T, R>(this, mapper, delayErrors, maxConcurrency, bufferSize));
    }
Returns a Flowable that emits items based on applying a function that you supply to each item emitted
by the source Publisher, where that function returns a Publisher, and then merging those resulting
Publishers and emitting the results of this merger, while limiting the maximum number of concurrent
subscriptions to these Publishers.
<!-- <p> -->
<!-- <img width="640" height="310" src="https://raw.github.com/wiki/ReactiveX/RxJava/images/rx-operators/flatMap.png" alt=""> -->
<dl>
<dt><b>Backpressure:</b></dt>
<dd>The operator honors backpressure from downstream. The upstream Flowable is consumed
in a bounded manner (up to {@code maxConcurrency} outstanding request amount for items).
The inner {@code Publisher}s are expected to honor backpressure; if violated,
the operator <em>may</em> signal {@code MissingBackpressureException}.</dd>
<dt><b>Scheduler:</b></dt>
<dd>{@code flatMap} does not operate by default on a particular {@link Scheduler}.</dd>
</dl>

@param <R> the value type of the inner Publishers and the output type
@param mapper
a function that, when applied to an item emitted by the source Publisher, returns a
Publisher
@param maxConcurrency
the maximum number of Publishers that may be subscribed to concurrently
@param delayErrors
if true, exceptions from the current Flowable and all inner Publishers are delayed until all of them terminate
if false, the first one signaling an exception will terminate the whole sequence immediately
@param bufferSize
the number of elements to prefetch from each inner Publisher
@return a Flowable that emits the result of applying the transformation function to each item emitted
by the source Publisher and merging the results of the Publishers obtained from this
transformation
@see <a href="http://reactivex.io/documentation/operators/flatmap.html">ReactiveX operators documentation: FlatMap</a>
@since 2.0