Обычно, когда мы хотим запустить наш код параллельно, мы используем методы Promise.all() и Promise.allSettled(). К сожалению, в некоторых случаях мы не можем его использовать. Например, когда нам действительно важно выполнять обещания в определенном порядке, и у нас также есть код, который подготавливает некоторые данные между ними.

Давайте рассмотрим пример, когда мы хотим создать книгу в нашей базе данных, и книга должна иметь страницы и имя.

Типичный пример с «ожиданием»:

// preparing data that takes quite some time
const thousandsOfPages = await getAllPages();
const sortedPages = thousandsOfPages.sort();
// we are waiting for this promise to resolve for quite some time and blocking promise createBook from execution
const bookName = await getBookName();
const bookWithPages = await createBook(sortedPages);

Тот же пример, но с Promise.all():

// preparing data that takes quite some time
const thousandsOfPages = await getAllPages();
const sortedPages = thousandsOfPages.sort();
// running promises in parallel
const [bookName, bookWithPages] = await Promise.all([getBookName(); createBook(sortedPages)]);

Проблема с приведенным выше примером заключается в том, что createBook() может быть разрешен первым, а getBookName() может быть отклонен вторым. И по нашей первоначальной идее мы не хотели создавать книгу в нашей базе данных, не убедившись, что у нас уже есть название книги. Итак, теперь нам нужно обработать случай отката книги без названия из нашей базы данных, а мы этого не хотим.

Пример с «promise-on-the-go» или умным async/await:

// getting a promise. We are NOT blocking the code below from execution
const bookNamePromise = getBookName();
// preparing data that takes quite some time
const thousandsOfPages = await getAllPages();
const sortedPages = thousandsOfPages.sort();
// by the time it goes to this line bookNamePromise may probably be already resolved or be very close to it so we don't wait as long as in the first code example
const bookName = await bookNamePromise;
const bookWithPages = await createBook(sortedPages);

Вывод:

Подход «Promise-on-the-go» не так сильно блокирует выполнение кода, как «ожидание», а также гарантирует порядок выполнения, в то время как Promise.all() и Promise.allSettled() этого не делают.