07. Promise Composition
Существует две системных функции для комбинирования Promise:
Promise.all
соответствует приему "для всех".Promise.race
соответствует принципу winner takes it all.
Promise.all
Promise.all
Метод Promise.all(array: Promise)
принимает на вход массив Promise и возвращает новый Promise, который будет выполнен когда пока все входящие в него Promise будут выполнены.
Promise.all()
и возвращает массив результатов.Note that even if a single dependency is rejected, the
Promise.all
method will be rejected entirely as well.If an empty iterable is passed, then this method returns (synchronously) an already resolved promise.
If all of the passed-in promises fulfill, or are not promises, the promise returned by
Promise.all()
is fulfilled asynchronously.If any of the passed-in promises reject,
Promise.all
asynchronously rejects with the value of the promise that rejected, whether or not the other promises have resolved.
Promise.all
is good for executing many promises at once:
Promise.race
Promise.race
The Promise.race(iterable)
method returns a promise that resolves or rejects as soon as one of the promises in the iterable resolves or rejects, with the value or reason from that promise.
Результатом будет только первый settled Promise из списка (неважно как - успешно или неуспешно).
Успешным считается любой Promise, даже если он был rejected.
Остальные игнорируются.
If the iterable passed is empty, the promise returned will be forever pending.
Promise.race
is good for setting a timeout:
Promise.allSettled
Promise.allSettled
returns a promise that’s fulfilled with an array of promise state snapshots, but only after all the original promises have settled; i.e. become either fulfilled or rejected.
Sequential promise execution
One solution is to run the Promises in series, or one after the other. Unfortunately there’s no simple analog to Promise.all
in ES6 (why?), but Array.reduce
can help us:
Такое использование reduce
гарантирует, что then будут вызываться последовательно, один за другим, формируя последовательное исполнение. Можно использовать forEach
, но это будет случайное исполнение:
Serial queue of events
It is possible to imitate serial queue of events using promises:
Dynamic chains
Sometimes we want to construct our Promise chain dynamically, e.g. inserting an extra step if a particular condition is met. Be sure to update the value of promise by writing promise = promise.then(/*...*/)
.
Passing data between Promise callbacks
The following code illustrates a common problem with Promise callbacks: The variable connection (line A) exists in one scope, but needs to be accessed in other scopes (line B, line C).
We can solve this problem with Promises if we nest Promise chains:
There are two Promise chains:
The first Promise chain starts in line
A
. connection is the asynchronously delivered result ofopen()
.The second Promise chain is nested inside the
.then()
callback starting in lineB
. It starts in lineC
. Note the return in lineC
, which ensures that both chains are eventually merged correctly.
The nesting gives all callbacks in the second chain access to connection.
Another solutions for the same problem:
multiple return values
local variable and side effects (worst scenario)
async
/await
Last updated
Was this helpful?