Like select {} statement in Go: allows to concurrently try to write into/read from
multiple channels, whichever is writable/readable first
Extended to support any promises: takes in operations (those can be
of different types, e.g. Promise), waits for the first one to complete,
returns its result, and cancels the remaining ones
Operation types:
Promise<T> - waits for the promise to resolve/reject. Cannot be cancelled
(signal: AbortSignal) => Promise<T> - called "abortable function".
Wait for the returned promise. Can be cancelled: when this operation looses
the race, signal is aborted
null - noop that never wins the race. Useful for conditional operations,
e.g. select({ maybeOp: doOp ? op() : null })
Examples:
Reading from/writing into channels
Read from channel a or b, whichever is readable first:
awaitselect({ a:a.raceRead(), b:b.raceRead() })
Compare this to:
awaitPromise.race([a.read(), b.read()])
The former reads either from a or b, but never from both. The later reads
from both, returns the value of the one that wins the race, but
does not cancel the read. If a wins, a value from b is lost
Like
select {}statement in Go: allows to concurrently try to write into/read from multiple channels, whichever is writable/readable firstExtended to support any promises: takes in operations (those can be of different types, e.g.
Promise), waits for the first one to complete, returns its result, and cancels the remaining onesOperation types:
Promise<T>- waits for the promise to resolve/reject. Cannot be cancelled(signal: AbortSignal) => Promise<T>- called "abortable function". Wait for the returned promise. Can be cancelled: when this operation looses the race,signalis abortedSelectable<T>- used by ReadableChannel.raceRead, WritableChannel.raceWrite.null- noop that never wins the race. Useful for conditional operations, e.g.select({ maybeOp: doOp ? op() : null })Examples:
Reading from/writing into channels
Read from channel
aorb, whichever is readable first:Compare this to:
The former reads either from
aorb, but never from both. The later reads from both, returns the value of the one that wins the race, but does not cancel the read. Ifawins, a value frombis lostReadableChannel.raceRead returns a Selectable which allows cancellation, unlike ReadableChannel.read, which returns a
Promiseand cannot be cancelledSimilarly, writes can be raced with
Read from a channel or time out
Note that this aborts the timer if reading wins the race. If you want to keep the timeout for multiple operations, pass
Promiseinstead of function:Read from a channel or abort on signal
Fairly select between settled promises
Compare with:
If
promiseAandpromiseBare both settled,Promise.racewill always choosepromiseA, whereasselectwill choose at randomDetailed semantics
Similar to
Promise.race, resolves once any operation completes successfully, rejects one any operation fails (throws)"Operation fails" means:
Promise<T>- promise rejects(signal?: AbortSignal) => Promise<T>- the returned promise rejectsSelectable<T>- Selectable.wait or Selectable.attempt thrownulloperations never complete, therefore never failException thrown by operation is wrapped in SelectError, which has SelectError.argName to tell which operation has failed
If multiple operations are ready, randomly selects which one wins the race
"Operation is ready" means:
Promise<T>- promise is settledSelectable<T>- promise returned by {@link Selectable.wait} is settlednulloperations are never ready