Разрешение Promise в JS вне конструктора: лучшие практики
Пройдите тест, узнайте какой профессии подходите
Быстрый ответ
let externalResolve, externalReject;
const myPromise = new Promise((resolve, reject) => {
externalResolve = resolve;
externalReject = reject;
});
// Мы можем подтвердить Promise из любого участка нашего кода!
externalResolve('Выполнено!');
// Используем это, например, с асинхронным выводом в консоль
myPromise.then(console.log); // Выведет 'Выполнено!'
Создаваемый нами объкт "отложенного" типа позволяет управлять подтверждением или отклонением Promise из любого места в коде.
Погружение в отложенные шаблоны
Отложенные шаблоны предоставляют нам возможность гибкого управления промисами за счёт создания инкапсулированной модели с функциями resolve
и reject
, доступ к которым можно получить извне. Рассмотрим их подробнее:
function Deferred() {
this.promise = new Promise((resolve, reject) => {
this.resolve = resolve;
this.reject = reject;
});
}
const deferred = new Deferred();
deferred.promise.then(value => console.log(value));
deferred.resolve('Выполнено из вне!'); // Выведет 'Выполнено из вне!'
Пример показывает, как класс Deferred
скрывает детали реализации промисов, делая код более чистым и понятным. Использование отложенных шаблонов существенно улучшает поддержку и читаемость кода.
Правильная работа с подтверждением промисов
Управление промисами извне позволяет точно определять, когда и как они будут подтверждены или отклонены. Используйте это для реагирования на события из внешнего источника.
Обратите внимание на то, чтобы избегать создания промисов в условных конструкциях. Лучше работайте с одним промисом, который будет перенаправлен на исполнение в зависимости от установленных условий, это поможет избежать неожиданных ошибок и добавит консистентности вашему коду.
Мастерство построения цепочек промисов и async/await
Перед тем, как использовать внешнее управление промисами, стоит подумать о возможности применения цепочек промисов. Этот подход позволяет организовывать последовательное и предсказуемое выполнение асинхронных задач.
Применение async/await
в сочетании с отложенными шаблонами может существенно упростить понимание вашего кода:
async function runDeferred(deferred) {
const longAwaitedValue = await deferred.promise;
console.log(longAwaitedValue);
}
const deferred = new Deferred();
runDeferred(deferred);
setTimeout(() => {
deferred.resolve('Неожиданное исполнение!');
}, 2000);
Не забывайте также использовать Promise.prototype.finally
для очистки ресурсов после выполнения промисов.
Внедрение отложенных шаблонов в задачи
Создание задачи с встроенным "отложенным" обещанием улучшает контроль над подтверждением и отклонением промиса, делая его адаптируемым под различные сценарии.
class Task {
constructor(executor) {
const deferred = new Deferred();
this.promise = deferred.promise;
this.resolve = deferred.resolve;
this.reject = deferred.reject;
executor(this.resolve, this.reject);
}
}
const task = new Task((resolve, reject) => {
// Здесь идёт реализация вашей задачи.
});
task.promise.then(console.log);
task.resolve('Задача решена, можно остановиться на чае.');
Используйте устоявшиеся шаблоны программирования для создания отложенных объектов, и внешний контроль над промисами станет вашим сильным инструментом в арсенале.
Визуализация
Давайте представим процесс управления промисами, представив его как дистанционное открытие замка:
Обещание: [🔒] (Замок)
УправлениеСнаружи: [🔑] (Ключ от замка)
Мы создаём Promise
и связываем метод resolve
c gateUnlock
:
let gateUnlock;
const gatePromise = new Promise((resolve, reject) => {
gateUnlock = resolve; // Передаём ключ
});
Когда мы используем ключ:
gateUnlock(); // Открывает замок
Статус промиса меняется с "заблокировано" на "разблокировано":
Состояние Обещания: Заблокировано [🔒] => Разблокировано [🚪]
Глобальное управление промисами
Для большего удобства можно определить методы resolve
и reject
в качестве глобальных переменных. Однако не забывайте, что избыток глобальных переменных может привести к "загрязнению" пространства имен.
Async/await в сочетании с отложенными обещаниями для упрощения чтения кода
Ясная связь между async/await
и промисами достигается за счёт использования шаблона Deferred
. Этот подход способствует более стройной организации асинхронного кода.
Полезные материалы
- Использование промисов – JavaScript | MDN — Детальное руководство по работе с Promises.
- Основы JavaScript Promises | web.dev — Подробное объяснение принципов работы промисов.
- Promise – JavaScript.info — Разбор метода
.then()
. - Async/await – JavaScript.info — Гармония между async/await и промисами.
- Понимание промисов в JavaScript | DigitalOcean — Руководство по реализации промисов в JavaScript.
- Глубокое понимание промисов в JavaScript | DigitalOcean — Подробное изучение промисов.