Deferred Promise
Описание
Утилита для создания Promise с внешним управлением его состоянием. Позволяет разделить создание Promise и его разрешение/отклонение, что особенно полезно при работе с асинхронными операциями в разных частях приложения.
Назначение
Модуль решает следующие задачи:
- Управление состоянием Promise извне
- Работа с группами Promise
- Синхронизация асинхронных операций
Использование
Базовый пример
// Создаём отложенный Promise
const deferred = new DeferredPromise<string>();
// Подписываемся на его разрешение
deferred.promise.then(result => {
console.log('Получен результат:', result);
});
// Где-то в другом месте разрешаем Promise
deferred.resolve('Готово!');
Работа с группами Promise
// Создаём массив Promise
const deferreds = [
new DeferredPromise<number>(),
new DeferredPromise<number>(),
new DeferredPromise<number>()
];
// Разрешаем все Promise одним значением
DeferredPromise.resolveAll(deferreds, 42);
// Или ждём завершения всех
const results = await DeferredPromise.all(deferreds);
Гонка Promise
const racers = [
new DeferredPromise<string>(),
new DeferredPromise<string>()
];
// Получаем результат первого разрешённого Promise
const winner = await DeferredPromise.race(racers);
API
Класс DeferredPromise
Свойства
promise: Promise<T>
- управляемый Promiseresolve: (value: T) => void
- функция для разрешения Promisereject: (reason?: any) => void
- функция для отклонения Promise
Статические методы
resolveAll<K>(deferred: DeferredPromise<any>[], data: K): void
- разрешает все Promise одним значениемrejectAll(deferred: DeferredPromise<any>[], reason?: any): void
- отклоняет все Promise с одной причинойall(deferred: DeferredPromise<any>[]): Promise<any[]>
- ждёт разрешения всех PromiseallSettled(deferred: DeferredPromise<any>[]): Promise<any[]>
- ждёт завершения всех Promiserace(deferred: DeferredPromise<any>[]): Promise<any>
- возвращает первый разрешённый Promise
Примеры использования
Реализация таймера
function createTimer(ms: number): DeferredPromise<void> {
const timer = new DeferredPromise<void>();
setTimeout(() => timer.resolve(), ms);
return timer;
}
// Использование
const timer = createTimer(1000);
await timer.promise; // Ждём 1 секунду
Загрузка ресурсов
class ResourceLoader {
private loadingStates = new Map<string, DeferredPromise<Resource>>();
public load(url: string): Promise<Resource> {
// Проверяем, не загружается ли уже ресурс
const existing = this.loadingStates.get(url);
if (existing) {
return existing.promise;
}
// Создаём новый DeferredPromise для этой загрузки
const deferred = new DeferredPromise<Resource>();
this.loadingStates.set(url, deferred);
// Начинаем загрузку
fetch(url)
.then(response => response.json())
.then(data => {
deferred.resolve(new Resource(data));
this.loadingStates.delete(url);
})
.catch(error => {
deferred.reject(error);
this.loadingStates.delete(url);
});
return deferred.promise;
}
}
Частые вопросы
Когда использовать DeferredPromise?
DeferredPromise особенно полезен в следующих случаях:
- Когда нужно управлять состоянием Promise из разных мест
- Для синхронизации асинхронных операций
- При работе с группами Promise
В чём отличие от обычного Promise?
Обычный Promise требует передачи функций resolve/reject в конструктор, что делает невозможным управление им извне. DeferredPromise предоставляет эти функции как публичные методы.
Как обрабатывать ошибки?
Используйте метод reject
для отклонения Promise:
const deferred = new DeferredPromise<string>();
try {
// Что-то пошло не так
deferred.reject(new Error('Ошибка!'));
} catch (error) {
deferred.reject(error);
}