code: public final <TRight, TLeftEnd, TRightEnd, R> Flux<R> join(
  			Publisher<? extends TRight> other,
  			Function<? super T, ? extends Publisher<TLeftEnd>> leftEnd,
  			Function<? super TRight, ? extends Publisher<TRightEnd>> rightEnd,
  			BiFunction<? super T, ? super TRight, ? extends R> resultSelector
  	) {
  		return onAssembly(new FluxJoin<T, TRight, TLeftEnd, TRightEnd, R>(
  				this, other, leftEnd, rightEnd, resultSelector));
  	}
docs: Map values from two Publishers into time windows and emit combination of values
  in case their windows overlap. The emitted elements are obtained by passing the
  values from this {@link Flux} and the other {@link Publisher} to a {@link BiFunction}.
  <p>
  There are no guarantees in what order the items get combined when multiple items from
  one or both source Publishers overlap.
  
  <p>
  <img class="marble" src="doc-files/marbles/join.svg" alt="">
  
  
  @param other the other {@link Publisher} to correlate items with
  @param leftEnd a function that returns a Publisher whose emissions indicate the
  time window for the source value to be considered
  @param rightEnd a function that returns a Publisher whose emissions indicate the
  time window for the {@code right} Publisher value to be considered
  @param resultSelector a function that takes an item emitted by each Publisher and returns the
  value to be emitted by the resulting {@link Flux}
  @param <TRight> the type of the elements from the right {@link Publisher}
  @param <TLeftEnd> the type for this {@link Flux} window signals
  @param <TRightEnd> the type for the right {@link Publisher} window signals
  @param <R> the combined result type
  
  @return a joining {@link Flux}
  @see #groupJoin(Publisher, Function, Function, BiFunction)