QUESTION: Як виконати async паралельно?
Для того щоб ефективно виконати асинхронні операції паралельно в сучасному JavaScript, найбільш надійним і елегантним рішенням є використання вбудованої конструкції await Promise.all([fn1(), fn2()]). Головна помилка розробників-початківців полягає в тому, що вони послідовно викликають кожну асинхронну функцію через окремі оператори await, що призводить до непотрібного блокування потоку виконання та збільшення загального часу очікування. Коли ви передаєте масив промісів у Promise.all, усі асинхронні завдання запускаються одночасно, а виконання коду призупиняється рівно до того моменту, поки не завершиться найдовший із них.
Результати виконання всіх переданих функцій повертаються у вигляді єдиного впорядкованого масиву, що дозволяє легко отримати до них доступ. Для зручності роботи часто застосовується синтаксис деструктуризації, наприклад, const [a, b] = await Promise.all([fetchDataA(), fetchDataB()]), що робить код чистим і читабельним. Проте варто пам'ятати важливу особливість: якщо хоча б один із промісів у масиві завершиться з помилкою (буде відхилений), увесь Promise.all негайно завершиться з помилкою, а решту результатів буде проігноровано.
Якщо у вашій бізнес-логіці критично важливо отримати результати абсолютно всіх запитів, незалежно від того, завершилися вони успіхом чи падінням, замість Promise.all слід використовувати метод Promise.allSettled. Він повертає масив об'єктів, що описують статус кожного промісу (fulfilled або rejected) разом із його значенням чи причиною помилки. Це дає максимальну гнучкість під час обробки пакетних мережевих запитів, читання файлів або виконання інших незалежних одна від одної асинхронних операцій у веб-додатку.