本页尚未翻译,因此以英文显示。 参与翻译

mapEither & mapEitherAsync

Run each event in its own raise scope: r.raise (and r.ensure / r.bind) becomes a Left, a normal return a Right.

FxEvents<Either<E, R>> FxEvents<T>.mapEither<E, R>(R Function(Raise<E> r, T value) f) FxEvents<Either<E, R>> FxEvents<T>.mapEitherAsync<E, R>(FutureOr<R> Function(Raise<E> r, T value) f)

Lecture

attempt is the boundary conversion — it turns whatever is already on the error channel into a Left. mapEither is the operator you reach for after that, or on a clean source: each event runs inside an either builder, so you write straight-line Dart with r.ensure / r.raise and the result of the whole map is Either<E, R>. A failing event does not cancel the source; later events still arrive.

A thrown exception stays on the error channel — that is the either builder's contract, and it keeps attempt the single place where a throw turns into a value. When a callback both raises and throws, prefer eitherCatching inside mapEither so one Either comes out.

mapEitherAsync is the async twin: one event at a time, like asyncMap. eitherAsync's rule carries over: a raise must happen inside the awaited chain. A raise from an unawaited future outlives the scope and surfaces as an unhandled zone error instead of a Left.

A source error passes through both operators untouched. Convert those with attempt upstream when you want them as Lefts too.

Demo 1 · A raise becomes Left, a return becomes Right

Demo 2 · mapEitherAsync, one event at a time

Try it yourself

Exercise: a thrown exception stays on the error channel, and the chain continues past it.

Related: attempt — the boundary that turns a throw into a Left · either builder — the same raise scope, on a single value · rights / separated — split the resulting Eithers