Коротка відповідь
juniorAsync disposer — це патерн, що дозволяє асинхронно звільняти ресурси після завершення роботи. Він реалізується через метод `dispose()` або `close()`, що повертає Promise, і використовується в конструкціях типу `try…finally` або `using` (ES2024).
Повне пояснення
Що це і навіщо
- Патерн async disposer забезпечує чисте завершення асинхронних ресурсів (файли, мережеві з’єднання, таймери). Без нього ресурси можуть залишатися відкритими, що призводить до витоків.
Ключові принципи
- Метод
dispose()повертає Promise. - Використовується в
try…finallyабо новій синтаксичній конструкціїusing. - Підтримується в TypeScript через інтерфейс
AsyncDisposable.
Як це працює
class FileHandler implements AsyncDisposable {
private fd: number;
constructor(fd: number) { this.fd = fd; }
async dispose() {
await fs.promises.close(this.fd);
}
}
async function process() {
const fh = new FileHandler(fd);
try {
// робота з файлом
} finally {
await fh.dispose();
}
}
Практика і реалізація
- У TS:
interface AsyncDisposable { dispose(): Promise<void>; }. - У JS (ES2024):
using fh = new FileHandler(fd);автоматично викликаєdispose().
Тестування
- Використовувати Jest/Vitest:
test('dispose called', async () => {
const mock = jest.fn().mockResolvedValue(undefined);
class Dummy implements AsyncDisposable { dispose() { return mock(); } }
const d = new Dummy();
await d.dispose();
expect(mock).toHaveBeenCalled();
});
Оптимізація та edge‑cases
- Переконатися, що
dispose()не блокує інші асинхронні операції. - Обробляти помилки в
dispose()черезtry…catchабоfinally. - У випадку багатьох ресурсів використовувати
Promise.allSettled()для одночасного закриття.
Часті помилки
- Забудьте викликати
dispose()→ витік. - Не обробляйте помилки в
dispose()→ crash. - Використання синхронного
closeу асинхронному коді → блокування. - Не використовувати
usingу TS 5.0+ → не автоматичне закриття. - Перевантаження
dispose()без очікування → непередбачувана послідовність. - Відсутність типу
AsyncDisposable→ помилки під час компіляції. - Виклик
dispose()після вже закритого ресурсу → помилка. - Не врахування
AbortSignalуdispose()→ некоректне завершення.
Cheatsheet
dispose(): Promise<void>– асинхронне закриття.using(ES2024) – автоматичний викликdispose().- TS:
implements AsyncDisposable. - Тест:
await instance.dispose(); expect(mock).toHaveBeenCalled();