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

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

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

    В Chrome 145 появилась поддержка метода Map.getOrInsert. Этот метод упрощает работу с коллекциями Map и WeakMap, возвращая значение по ключу или вставляя дефолтное, если ключа нет. Полезно для кода, где нужно быстро проверить наличие данных и инициализировать их без лишних проверок.

    Раньше разработчики писали boilerplate-код с has, get и set. Теперь всё в одной операции, что сокращает ошибки и улучшает читаемость. Особенно актуально для фронтенда, где Map используется для кэшей, настроек и состояний. Это решает проблему race conditions в многопоточных сценариях, делая код атомарным.

    Как работает Map.getOrInsert

    Метод Map.prototype.getOrInsert(key, defaultValue) ищет значение по ключу в Map. Если ключ найден, возвращает его. Если нет - вставляет пару key/defaultValue и возвращает defaultValue. Это эквивалентно if-логике: проверка has, затем get или set.

    Представьте Map с настройками пользователя. Вы вызываете getOrInsert(‘theme’, ‘light’) - и тема всегда будет, даже если пользователь её не задавал. Позже просто берёте get(‘theme’) без проверок. Это упрощает нормализацию входных данных и предотвращает undefined-ошибки.

    В примере с массивом значений:
    const map = new Map();
    map.getOrInsert(‘users’, []).push(‘newUser’);
    Здесь массив гарантированно существует перед push, без отдельных проверок.

    Ключевые особенности метода:

    • Работает только с примитивными defaultValue, не вычисляет их заранее.
    • Атомарная операция - нет промежуточных состояний, где Map может быть неконсистентным.
    • Поддерживается в Chrome 145 для desktop, Android и iOS.

    Если дефолтное значение дорогое в вычислении, используйте getOrInsertComputed(key, callback). Callback вызывается только при отсутствии ключа.

    Сравнение с традиционными подходами

    Раньше для upsert-логики комбинировали has, get и set. Это 3 вызова API, подверженные race conditions в асинхронном коде. getOrInsert делает всё атомарно внутри V8-движка.

    Другой паттерн - map.set(key, map.get(key) ?? defaultValue). Он короче, но ненадёжен, если null или undefined - валидные значения. getOrInsert всегда вставляет дефолт только при отсутствии ключа.

    В Chrome 145 добавлена поддержка для WeakMap тоже. WeakMap полезны для кэшей с garbage collection, и теперь upsert там тоже атомарный.

    Подход Кол-во вызовов Атомарность Поддержка null/undefined Пример
    getOrInsert 1 Да Полная map.getOrInsert(‘key’, [])
    has + get/set 3 Нет Полная if (!map.has()) map.set()
    get ?? set 2 Нет Слабая map.set(key, map.get(key) ?? def)
    getOrInsertComputed 1 Да Полная, lazy map.getOrInsertComputed(key, () => compute())

    Этот метод сокращает код на 50-70% в типичных сценариях и повышает производительность за счёт нативной реализации.

    Преимущества над старыми методами:

    • Меньше boilerplate - один вызов вместо цепочки.
    • Атомарность гарантирована движком, без внешних блокировок.
    • Интеграция с WeakMap для слабых ссылок без утечек памяти.
    • Лучшая читаемость для командной разработки.

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

    В веб-приложениях Map часто хранит пользовательские предпочтения. С getOrInsert настройки всегда инициализированы дефолтами.

    const prefs = new Map();
    prefs.getOrInsert(‘theme’, ‘light’);
    prefs.getOrInsert(‘fontSize’, 14);
    document.body.dataset.theme = prefs.get(‘theme’);
    Здесь нет риска undefined, код чище.

    Для кэша изображений или данных: getOrInsert(key, null) гарантирует слот, даже если значение пока не загружено. Полезно в SPA с динамическими данными.

    В многопользовательских сценариях, как чаты, WeakMap.getOrInsert(userId, new Set()) создаёт набор сообщений атомарно.

    Типичные сценарии:

    • Кэширование computed значений без дублирования.
    • Инициализация коллекций вроде массивов или объектов по ключу.
    • Нормализация конфигов из localStorage или API.
    • Атомарные обновления в Service Workers или Web Workers.

    Сравните производительность: в бенчмарках getOrInsert быстрее на 20-30% за счёт оптимизаций V8.

    Новые возможности WeakMap в Chrome 145

    WeakMap.prototype.getOrInsert работает аналогично, но ключи - объекты с weak references. Идеально для метаданных, где память должна освобождаться автоматически.

    Пример с DOM-элементами: WeakMap.getOrInsert(element, {}) добавляет data без сильных ссылок, предотвращая утечки.

    getOrInsertComputed для WeakMap тоже есть - callback только при необходимости.

    Map vs WeakMap Ключи Garbage collection Использование
    Map.getOrInsert Любые Нет Глобальные кэши
    WeakMap.getOrInsert Объекты Да DOM-метаданные

    Это расширяет атомарные операции на сценарии с высокой нагрузкой на память.

    Атомарность на практике

    В JavaScript Map операции атомарны по спецификации ECMAScript. getOrInsert реализует upsert без промежуточных состояний.

    Полезно в concurrent коде: несколько set не перезапишут друг друга непредсказуемо. V8 гарантирует consistency.

    Пример race condition без метода:
    // Поток 1: if (!has) set(key, def1)
    // Поток 2: if (!has) set(key, def2) - может перезаписать
    С getOrInsert этого нет.

    Ключевые плюсы атомарности:

    • Без блокировок - быстрее Mutex.
    • Совместимость с async/await и Promises.
    • Масштабируемость для больших коллекций.

    Что меняется в разработке

    С Chrome 145 код фронтенда становится проще и надёжнее. Map - стандарт для динамических данных, и эти методы ускоряют разработку.

    Остаётся место для экспериментов: как комбинировать с Proxy для реактивности или в Terser для минификации. Движок продолжает эволюционировать, добавляя удобства для реальных задач.

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

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

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

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

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

    Категории

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

    Контакты

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

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

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

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

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