Стендап Сьогодні 📢 Канал в Telegram @stendap_sogodni

🤖🚫 Контент вільний від AI. Цей пост на 100% написаний людиною, як і все на моєму блозі. Насолоджуйтесь!

06.10.2023

Використання Promise для побудови лінивих обчислень

Натрапив на цікаве використання Promise в JavaScript. Зазвичай Promise це механізм асинхронного виконання, більше необхідна поступка ніж щось корисне. Проте є цікавий аспект: один раз виконаний Promise зберігає своє значення і далі.

Коли у вас уже є Promise, на ньому можна викликати .then() (та .catch()) скільки завгодно разів. Такі виклики призведуть до невідкладного виконання відповідного обробника. Після завершення поточного фрейму виконання, звісно, тобто семантика зберігається.

Що це нам дає? Зустрічаються випадки, коли один та той самий результат асинхронного виконання потрібний у двох місцях. Наприклад: завантажуємо з сервера текст поста, який можна або редагувати, або переглядати. Причому ми хочемо завантажувати його тільки якщо відкритий той чи інший режим. Та точно не хочемо повторювати це двічі.

Можна звісно зробити менеджер стану (як Redux), а також механізм повідомлення про готовність. Може, використати EventEmitter та підписки.

Але як альтернатива до всього цього, можна зберігати сам Promise. Тобто результат виконання fetch(). При першому виклику робимо завантаження та зберігаємо Promise; а при наступних просто повертаємо той самий Promise. Споживачі нічого не знають про ці деталі реалізації, а просто отримують Promise з потрібними даними. В тому числі не буде проблеми, якщо другий виклик відбудеться до отримання результату, тобто Race Condition.

Так можна будувати й складніші ланцюги перетворень — я навів найпростіший приклад. Тобто проміжні результати виконання теж зберігати так само. Можна мати цілий граф, як в reselect, тільки асинхронно. Насправді коли про це згадав, то дійсно вся ідея схожа на reselect, та, можливо, може бути прямо там реалізована.