TGStat
TGStat
Введите текст для поиска
Расширенный поиск каналов
  • flag Russian
    Язык сайта
    flag Russian flag English flag Uzbek
  • Вход на сайт
  • Каталог
    Каталог каналов и чатов Региональные подборки Тематические подборки Платные каналы Поиск каналов
    Добавить канал/чат
  • Рейтинги
    Рейтинг каналов Рейтинг чатов Рейтинг публикаций
    Рейтинги брендов и персон
  • Аналитика
  • Поиск по публикациям
  • Мониторинг Telegram
  • Продвижение
    Реклама через Яндекс Бизнес Реклама в каналах через TGStat Agency Реклама на сайте TGStat.ru
Настя Котова // Frontend & Node.js

5 Oct, 18:57

Открыть в Telegram Поделиться Пожаловаться

В постах про using мы разбирали, как освобождение ресурса привязывается к границам блока. Но у этого подхода есть предел: объявлений должно быть столько же, сколько ресурсов, и все они должны быть известны на момент написания кода. Для случаев, когда ресурсов заранее неизвестное количество, в стандарте есть DisposableStack и его асинхронный вариант AsyncDisposableStack.

Допустим, надо открыть файлы по списку путей и поработать со всеми сразу. Написать объявление в цикле не выйдет, потому что тело цикла — это отдельная область, и файл закроется на своей же итерации, а не в конце.

Стек решает это тем, что накапливает ресурсы по ходу дела, но сам при этом подчиняется тому же протоколу. То есть объявляется через using, и когда блок заканчивается, освобождает всё накопленное в обратном порядке.


await using stack = new AsyncDisposableStack();

const files = [];
for (const p of paths) {
const file = stack.use(await open(p));
files.push(file);
}
// работаем со всеми файлами


Метод use() кладёт объект в стек и возвращает его же, поэтому вызов удобно писать прямо вокруг выражения, которое ресурс создаёт, то есть так stack.use(await open(p)). В документации советуют не разносить получение ресурса и регистрацию на две строки, чтобы между ними не появился код, который может упасть. Ведь в этот момент стек ещё не знает про ресурс, а значит, не может его закрыть.

Также у стека есть метод adopt(). Он принимает значение и функцию для очистки, которая получит это значение аргументом:


stack.adopt(setInterval(tick, 1000), clearInterval);


Таким образом, стек оказывается универсальнее самого using. Для using объект обязан иметь [Symbol.dispose], а стеку достаточно передать функцию для закрытия. Поэтому стек может иметь смысл даже для единственного ресурса, если у того нет нужного протокола:


using stack = new DisposableStack();
stack.adopt(handler, h => emitter.off('data', h));

523 0 6 1 11
Каталог
Каталог каналов и чатов Подборки каналов Поиск каналов Добавить канал/чат
Рейтинги
Рейтинг каналов Telegram Рейтинг чатов Telegram Рейтинг публикаций Рейтинги брендов и персон
API
API статистики API поиска публикаций API Callback
Наши каналы
@TGStat @TGStat_Chat @telepulse @TGStatAPI
Почитать
Академия TGStat Исследование Telegram 2019 Исследование Telegram 2021 Исследование Telegram 2023
Контакты
Справочный центр Поддержка Почта Вакансии
Всякая всячина
Пользовательское соглашение Политика конфиденциальности Публичная оферта
Наши боты
@TGStat_Bot @SearcheeBot @TGAlertsBot @tg_analytics_bot @TGStatChatBot