Pull to refresh

Promise — краткое руководство

Для автора это первая в жизни статья написанная где-либо и когда-либо.

Вступление

Цель данной статьи рассказать о жизненном цикле Promise и о отличиях методов all vs any vs race vs allSettled.
В данном тексте нет ничего супернаучного, поэтому могу предположить что статья расчитана на Junior+. 

Кратко

new Promise(resolve, reject) => {})
	.then(onFulfilled, onRejected)
	.catch(onRejected);

Promise.all(array);
Promise.any(array);
Promise.race(array);
Promise.allSettled(array)

Жизненный цикл Promise

Исходя из документации мы можем говорить что инстанс Promise имеет несколько динамически изменяемых сущностей:

  • State - может быть в трех состояниях, pending, fulfilled и rejected;

  • Fate - бывает в двух состояниях, unresolved или resolved;

  • Settled - имеет два состояния settled и unsettled.

Cразу после создания, промис находится в состоянии pending, следующим шагом может быть три варианта, первые два которые я упомяну это resolve(any) и reject(any), последним мы разберем resolve(thenable).

  • resolve(any) - переводим промис в состояние fulfilled, вызываем onFulfilled;

  • reject(any) - переводим промис в состояние rejected, вызываем onRejected;

  • resolve(promise)- если в качестве аргумента мы передадим в resolve другой промис то мы отложим resolve основного промиса до тех пор, пока не выполнится вложенный, а точнее пока он не станет settled, т.е. пока не перейдет в состояние fulfilled или rejected.

состояние

завершен?

установлен?

new Promise()

pending

-

-

resolve(promise)

pending *

resolved

-

resolve(any)

fulfilled

resolved

settled

reject(any)

rejected

resolved

settled

Пояснение:

Состояние - это сущность промиса, которая изменяется на протяжении его жизни в направлении от pending до fulfilled или rejected.

Завершен - это сущность промиса которая говорит о том, завершена ли работа текущего промиса (resolved), которая определяется вызовом метода resolve или reject, важно понимать что завершение работы не значит что значение установлено.

Установлен - это сущность промиса которая говорит о том, установлено ли значение для этого промиса, речь идёт о аргументах переданных в resolve или reject.

Отдельное внимание стоит обратить на случай, когда в качестве аргумента, в resolve передаётся значения в виде thenable объекта, в таком случае состояние основного промиса остается pending но при этом основной промис считается resolved, дальнейшая судьба основного промиса перекладывается на этот новый объект, и "значение" основного промиса будет равно "значению" thenable.

Сравнение all vs any vs race vs allSettled

Несколько промисов в один можно объеденить c помощью статических методов класса Promise:

  • all - нужны все выполненные

    • дожидаемся пока все промисы из array будут выполнены, в onFulfilled мы получаем массив результатов в том же порядке в каком были установлены промисы в начальном массиве;

    • в случае если хоть один промис из array будет отклонён, в onRejected мы получим причину первого отклоненного промиса.

  • any - нужен хотя бы один выполненный

    • дожидаемся когда хотя бы один промис из array выполнится, в onFulfilled мы получаем результат первого выполненного промиса;

    • в случае если все промисы из array будут отклонены, в onRejected мы получим AggregateError: All promises were rejected.

  • race - нужен первый завершенный

    • дожидаемся когда любой промис из array выполнится или отклонится, в onFulfilled мы получим результат первого такого промиса.

  • allSettled - нужны все завершенные

    • дожидаемся пока все промисы из array будут завершены, в onFulfilled мы получаем массив результатов в том же порядке в каком были установлены промисы в начальном массиве.

all

any

race

allSettled

если аргумент пустой массив

fulfilled
Promise

rejected
Promise

pending
Promise

fulfilled
Promise

становится fulfilled
когда

все resolved
или
один rejected

один resolved
или
все rejected

один resolved
или
один rejected

все resolved
и
все rejected

возвращает в коллбэк в случае fulfilled

все resolved
или
первый rejected

первый resolved
или
AggregateError

первый resolved
или
первый rejected

все resolved
и
все rejected

Пояснение: метод all
  • Если в метод all передать пустой массив Promise.all([]), то возвращаемый методом all промис становится fulfilled так как у него нет ни одного rejected промиса.

  • Если в метод all передать массив с промисами Promise.all([,,,]), то возвращаемый методом all промис становится fulfilled в двух случаях: если все промисы в массиве будут resolved или хотя бы один будет rejected.

  • Если возвращаемый методом all промис становится fulfilled то в соответствующий коллбэк отправляется массив данных от всех resolved промисов или данные от одного rejected промиса.

Пояснение: метод any
  • Если в метод any передать пустой массив Promise.any([]), то возвращаемый методом any промис становится rejected так как у него нет ни одного fulfilled промиса.

  • Если в метод any передать массив с промисами Promise.any([,,,]), то возвращаемый методом any промис становится fulfilled в двух случаях: если хотя бы один будет resolved или все промисы в массиве будут rejected.

  • Если возвращаемый методом any промис становится fulfilled то в соответствующий коллбэк отправляется данные от первого resolved промиса или AggregateError так ни один промис не закончился успешно.

Пояснение: метод race
  • Если в метод race передать пустой массив Promise.race([]), то возвращаемый методом race промис остается pending так как у него нет ни одного fulfilled промиса.

  • Если в метод race передать массив с промисами Promise.race([,,,]), то возвращаемый методом race промис остается pending до тех пор пока хотя бы один промис в массиве не станет resolved или rejected.

  • Если возвращаемый методом race промис становится fulfilled то в соответствующий коллбэк отправляется данные от первого resolved или первого rejected промиса.

Пояснение: метод allSettled
  • Если в метод allSettled передать пустой массив Promise.allSettled([]), то возвращаемый методом allSettled промис становится fulfilled.

  • Если в метод allSettled передать массив с промисами Promise.allSettled([,,,]), то возвращаемый методом allSettled промис становится fulfilled в случае: если все промисы в массиве будут settled.

  • Если возвращаемый методом allSettled промис становится fulfilled то в соответствующий коллбэк отправляется массив данных от всех settled промисов.

Tags:
Hubs:
You can’t comment this publication because its author is not yet a full member of the community. You will be able to contact the author only after he or she has been invited by someone in the community. Until then, author’s username will be hidden by an alias.