Избегаем антипаттерн явной конструкции обещаний в JS
Быстрый ответ
Антипаттерн явной конструкции промиса в JavaScript можно избежать, если не оборачивать в новый Promise
те функции, которые уже возвращают Promise
.
// Пример излишнего использования промиса 🚧
new Promise((resolve, reject) => {
asyncFunction().then(resolve).catch(reject);
});
// Верно ли это? Да, потому что это избыточно.
Оптимальный вариант будет выглядеть так:
// Чисто и лаконично 🍋
asyncFunction();
// Нет необходимости усложнять, если у вас уже есть готовое решение.
Таким образом сокращается сложность кода и уменьшается использование промисов.
Основные принципы для избежания ловушки явной конструкции промиса
Чтобы не угодить в ловушку явной конструкции промиса, следуйте нескольким рекомендациям:
1. Придерживайтесь цепочки промисов
Использование методов.then()
и .catch()
позволяет избежать излишней запутанности кода, делая его более лёгким и понятным.
2. Передавайте полученный промис
Если функция уже возвращает Promise
, то просто передайте этот промис, вместо создания нового.
3. Объекты отложенного выполнения: используйте с осторожностью
Объекты Deferred
лучше использовать только в случаях, когда это действительно необходимо – когда, например, требуется преобразовать API, не работающее с промисами, в совместимые.
4. Async/await для простоты и понятности кода
Оформление кода с помощью async/await
делает его чище и проще, особенно если его дополнить try/catch
блоками для обработки ошибок.
Визуализация
Вот как выглядит антипаттерн явной конструкции промиса:
// Антипаттерн: использование ракеты для ловли мухи 🚀🦟
new Promise((resolve, reject) => {
fs.readFile('file.txt', (err, data) => {
if (err) reject(err);
else resolve(data);
});
});
Лучший подход:
// Эффективный подход: мухобойка 🪰
const readFilePromise = util.promisify(fs.readFile);
readFilePromise('file.txt');
То есть, старайтесь использовать специализированные инструменты и функции, предназначенные для асинхронных задач, а не заставлять работать "тяжелую артиллерию".
Глубже в тему: практика и нюансы
Разберем более подробно применение этих принципов и возникающие при этом последствия:
1. Работа со сторонними библиотеками
При разработке с использованием сторонних библиотек сначала внимательно изучите их API и возможности. Если вы работаете с открытым кодом, то поищите способы связи с их авторами.
2. Композиция вместо создания
Если вы работаете с промисами, думайте о них как о деталях конструктора: вы можете сочетать их, но не должны создавать каждый раз с нуля.
3. Сотрудничество и взаимодействие
В случае трудностей на пути разработки, обратитесь за помощью к коллегам программистам или соответствующему сообществу.
4. Адаптация API к промисам
Для того чтобы преобразовывать библиотеки, работающие с обратными вызовами (callback), в API на основе промисов, используйте готовые решения, такие как util.promisify
.
5. Поддержание кода в актуальном состоянии
Регулярный рефакторинг и обновление асинхронного кода обеспечивают его легкочитаемость и уменьшают сложность.
Продвинутые техники работы с промисами
Приведём примеры некоторых продвинутых методов использования промисов для правильного управления сложными асинхронными процессами:
1. Группировка с помощью Promise.all
Promise.all
можно использовать для запуска и ожидания выполнения нескольких промисов параллельно.
2. Последовательное выполнение с использованием цепочки промисов
С использованием цепочки промисов можно последовательно выполнять асинхронные задачи, одну за другой.
3. Централизованное управление ошибками
Цепочки промисов предоставляют возможность эффективного управления ошибками, что упрощает отладку кода.
Полезные материалы
- Promise – JavaScript | MDN — подробная документация по работе с Promise в JavaScript.
- ECMAScript 2015 Language Specification – ECMA-262 6th Edition — официальная спецификация ECMAScript для Promise.
- JavaScript Promises: an introduction | Articles | web.dev — вводная статья по работе с промисами в JavaScript.
- javascript – What is the explicit promise construction antipattern and how do I avoid it? – Stack Overflow — обсуждение способов избегания антипаттерна явной конструкции промиса.
- ES6 Promises in Depth — глубокое погружение в мир промисов на ES6.
- Promises/A+ — открытый стандарт с описанием промисов в JavaScript.
- Understanding Asynchronous JavaScript | by Sukhjinder Arora | Bits and Pieces — статья о понимании асинхронности в JavaScript.