Map.getOrInsert в Chrome 145: атомарные операции для Map и WeakMap
-
В 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 для минификации. Движок продолжает эволюционировать, добавляя удобства для реальных задач.
Здравствуйте! Похоже, вас заинтересовала эта беседа, но у вас ещё нет аккаунта.
Надоело каждый раз пролистывать одни и те же посты? Зарегистрировав аккаунт, вы всегда будете возвращаться на ту же страницу, где были раньше, и сможете выбирать, получать ли уведомления о новых ответах (по электронной почте или в виде push-уведомлений). Вы также сможете сохранять закладки и ставить лайки постам, чтобы выразить свою благодарность другим участникам сообщества.
С вашими комментариями этот пост мог бы стать ещё лучше 💗
Зарегистрироваться Войти© 2024 - 2026 ExLends, Inc. Все права защищены.