Перейти к содержанию
  • Лента
  • Категории
  • Последние
  • Метки
  • Популярные
  • Пользователи
  • Группы
Свернуть
exlends
Категории
  1. Главная
  2. Категории
  3. Языки программирования
  4. JavaScript
  5. Chrome 145: Map.getOrInsert для атомарных операций

Chrome 145: Map.getOrInsert для атомарных операций

Запланировано Прикреплена Закрыта Перенесена JavaScript
chrome 145mapjavascript
1 Сообщения 1 Постеры 61 Просмотры
  • Сначала старые
  • Сначала новые
  • По количеству голосов
Ответить
  • Ответить, создав новую тему
Авторизуйтесь, чтобы ответить
Эта тема была удалена. Только пользователи с правом управления темами могут её видеть.
  • hannadevH Не в сети
    hannadevH Не в сети
    hannadev
    написал в отредактировано
    #1

    В Chrome 145 появился долгожданный метод getOrInsert() для объектов Map и WeakMap. Это не просто новая фишка - это решение реальной проблемы, с которой сталкиваются разработчики при работе с коллекциями. Метод позволяет получить значение по ключу или вставить новое значение за одну операцию, минуя лишние проверки.

    Это особенно полезно, когда вам нужно гарантировать наличие значения в объекте перед тем, как с ним работать. Вместо трёх строк кода теперь хватает одной - проще, безопаснее и эффективнее. Давайте разберёмся, как это работает и почему это важно для современной разработки.

    Что такое getOrInsert и зачем он нужен

    В традиционном подходе, чтобы получить значение из Map или установить его по умолчанию, приходилось писать проверку вручную. Вы проверяли наличие ключа через has(), потом либо получали значение через get(), либо устанавливали новое через set(). Это работает, но требует больше кода и оставляет место для ошибок.

    Метод getOrInsert() объединяет эти операции в одну атомарную операцию. Если ключ существует - вернёт его значение. Если нет - установит переданное значение по умолчанию и вернёт его. Всё просто и понятно. На практике это означает, что вы избегаете race-условий в асинхронном коде и пишете менее громоздкий код.

    Вот как выглядел старый способ:

    const map = new Map();
    let value;
    
    if (map.has('key')) {
      value = map.get('key');
    } else {
      value = 'default';
      map.set('key', value);
    }
    

    Теперь то же самое в одной строке:

    const value = map.getOrInsert('key', 'default');
    

    Разница очевидна - кода меньше, логики понятнее, и меньше шансов что-то упустить.

    Практические примеры использования

    Частый сценарий - работа с кешем или пулом значений. Представьте, что у вас есть Map, где каждому пользователю соответствует массив событий. Вам нужно добавить новое событие, но если массива для этого пользователя ещё не существует, создать его.

    Раньше это выглядело так:

    const userEvents = new Map();
    const userId = 123;
    const newEvent = { type: 'login', time: Date.now() };
    
    if (!userEvents.has(userId)) {
      userEvents.set(userId, []);
    }
    userEvents.get(userId).push(newEvent);
    

    С getOrInsert() становится проще:

    const userEvents = new Map();
    const userId = 123;
    const newEvent = { type: 'login', time: Date.now() };
    
    userEvents.getOrInsert(userId, []).push(newEvent);
    

    Ещё один полезный пример - инициализация конфигураций с дефолтными значениями. Это особенно актуально, когда вы нормализуете пользовательский ввод:

    const config = readUserConfig();
    config.getOrInsert('theme', 'light');
    config.getOrInsert('fontSize', 14);
    config.getOrInsert('notifications', true);
    
    // Теперь безопасно работаете с этими значениями
    document.body.dataset.theme = config.get('theme');
    

    Это избегает потребности в многократных проверках has() перед каждым get().

    Два варианта: getOrInsert и getOrInsertComputed

    Помимо базового getOrInsert(), в спецификацию добавлен и getOrInsertComputed(). В чём разница? Первый принимает готовое значение, второй - функцию, которая вычисляет значение только если оно действительно понадобилось.

    Это критично для производительности, когда вычисление дефолтного значения дорого. Не имеет смысла вычислять сложное значение, если ключ уже существует в Map. Давайте сравним:

    Метод Параметр Когда использовать Преимущество
    getOrInsert() Готовое значение Простые значения (строки, числа) Прямолинейный код
    getOrInsertComputed() Функция-колбэк Дорогие вычисления (API запросы, парсинг) Экономит ресурсы

    Пример использования getOrInsertComputed():

    const cache = new Map();
    
    // Функция вычисляется только если ключа нет
    const result = cache.getOrInsertComputed('expensive-key', () => {
      return someExpensiveOperation();
    });
    

    Здесь someExpensiveOperation() вызовется только когда ключа точно не существует в Map. Если ключ есть - функция никогда не выполнится.

    Поддержка браузерами и текущий статус

    Метод был впервые реализован в Chrome 145, но поддержка разная в разных браузерах. На момент 2026 года статус такой:

    • Chrome 145+: полная поддержка
    • Firefox 144+: полная поддержка
    • Safari 26.2+: полная поддержка
    • Edge: статус неясен, вероятно, впоследствии добавится
    • Старые версии всех браузеров: не поддерживают

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

    Механизм работает одинаково для обычных Map и для WeakMap - с той лишь оговоркой, что WeakMap хранит слабые ссылки на объекты-ключи.

    Как это влияет на качество кода

    Во-первых, меньше ошибок. Вы не случайно забудете проверить наличие ключа, потому что логика встроена в метод. Во-вторых, читаемость кода. Когда вы видите getOrInsert(), сразу понятно, что происходит - не нужно анализировать условия и цепочку операций.

    В-третьих, это лучшая производительность в многопоточной среде (при использовании Web Workers). Атомарность операции предотвращает гонку условий, где два потока могут одновременно попытаться установить значение для одного ключа.

    В-четвёртых, это стандарт ECMAScript, а не какой-то фреймворк или библиотека. Значит, вы полагаетесь на проверенный и оптимизированный движком код, а не самописный вспомогательный код.

    Список преимуществ getOrInsert() в контексте современной разработки:

    • Избегаете трёхстрочных конструкций if-has-set-get
    • Гарантируете безопасность в асинхронном коде
    • Экономите память благодаря ленивым вычислениям (через getOrInsertComputed)
    • Пишете код в соответствии с ECMAScript стандартом
    • Упрощаете тестирование и отладку логики с Map

    Что осталось за кадром

    Метод getOrInsert() - это хороший пример того, как стандарты эволюционируют на основе потребностей разработчиков. Долгое время это было частой критикой JavaScript - что для простых операций нужно писать много кода. Теперь эта боль постепенно уходит.

    Если вы работаете с новыми версиями браузеров или серверным JavaScript (Node.js), обязательно добавьте getOrInsert() в свой арсенал. Это один из тех инструментов, которые кажутся мелкой фишкой, но в большом проекте существенно упрощают жизнь и снижают количество багов. Стоит переглянуть старый код и найти места, где эта операция была бы полезнее классического подхода.

    1 ответ Последний ответ
    0

    Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.

    Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.

    С вашими комментариями этот пост мог бы стать ещё лучше 💗

    Зарегистрироваться Войти

    Категории

    • Главная
    • Новости
    • Фронтенд
    • Бекенд
    • Языки программирования

    Контакты

    • Сотрудничество
    • info@exlends.com

    © 2024 - 2026 ExLends, Inc. Все права защищены.

    Политика конфиденциальности
    • Войти

    • Нет учётной записи? Зарегистрироваться

    • Войдите или зарегистрируйтесь для поиска.
    • Первое сообщение
      Последнее сообщение
    0
    • Лента
    • Категории
    • Последние
    • Метки
    • Популярные
    • Пользователи
    • Группы