Разрешение Promise в JS вне конструктора: лучшие практики

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

JS
Скопировать код
let externalResolve, externalReject;

const myPromise = new Promise((resolve, reject) => {
  externalResolve = resolve;
  externalReject = reject;
});

// Мы можем подтвердить Promise из любого участка нашего кода!
externalResolve('Выполнено!');

// Используем это, например, с асинхронным выводом в консоль
myPromise.then(console.log); // Выведет 'Выполнено!'

Создаваемый нами объкт "отложенного" типа позволяет управлять подтверждением или отклонением Promise из любого места в коде.

Кинга Идем в IT: пошаговый план для смены профессии

Погружение в отложенные шаблоны

Отложенные шаблоны предоставляют нам возможность гибкого управления промисами за счёт создания инкапсулированной модели с функциями resolve и reject, доступ к которым можно получить извне. Рассмотрим их подробнее:

JS
Скопировать код
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 в сочетании с отложенными шаблонами может существенно упростить понимание вашего кода:

JS
Скопировать код
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 для очистки ресурсов после выполнения промисов.

Внедрение отложенных шаблонов в задачи

Создание задачи с встроенным "отложенным" обещанием улучшает контроль над подтверждением и отклонением промиса, делая его адаптируемым под различные сценарии.

JS
Скопировать код
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('Задача решена, можно остановиться на чае.');

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

Визуализация

Давайте представим процесс управления промисами, представив его как дистанционное открытие замка:

Markdown
Скопировать код
Обещание:        [🔒] (Замок)
УправлениеСнаружи: [🔑] (Ключ от замка)

Мы создаём Promise и связываем метод resolve c gateUnlock:

JS
Скопировать код
let gateUnlock;
const gatePromise = new Promise((resolve, reject) => {
  gateUnlock = resolve; // Передаём ключ
});

Когда мы используем ключ:

JS
Скопировать код
gateUnlock(); // Открывает замок

Статус промиса меняется с "заблокировано" на "разблокировано":

Markdown
Скопировать код
Состояние Обещания: Заблокировано [🔒] => Разблокировано [🚪]

Глобальное управление промисами

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

Async/await в сочетании с отложенными обещаниями для упрощения чтения кода

Ясная связь между async/await и промисами достигается за счёт использования шаблона Deferred. Этот подход способствует более стройной организации асинхронного кода.

Полезные материалы

  1. Использование промисов – JavaScript | MDN — Детальное руководство по работе с Promises.
  2. Основы JavaScript Promises | web.dev — Подробное объяснение принципов работы промисов.
  3. Promise – JavaScript.info — Разбор метода .then().
  4. Async/await – JavaScript.info — Гармония между async/await и промисами.
  5. Понимание промисов в JavaScript | DigitalOcean — Руководство по реализации промисов в JavaScript.
  6. Глубокое понимание промисов в JavaScript | DigitalOcean — Подробное изучение промисов.
Свежие материалы