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

Chrome 145: Map.getOrInsert для атомарных вставок

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

    JavaScript давно отстаёт от других языков программирования в удобстве работы с коллекциями. Если в Python или Go есть встроенный способ обновить значение или вставить его, если ключа нет, то в JavaScript приходилось писать условия. Но это меняется - Chrome 145 привносит долгожданное улучшение для Map и WeakMap с методом getOrInsert, который упрощает код и снижает вероятность ошибок.

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

    Почему это было нужно

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

    Такая операция называется upsert (update or insert) и давно используется в базах данных. Её суть - атомарная операция, которая гарантирует, что значение либо будет обновлено, либо вставлено, но никогда не случится промежуточное состояние. В JavaScript эту гарантию было сложно дать без дополнительных синхронизаций.

    Хотя JavaScript работает в однопоточной модели, где конкурентного доступа не бывает, сам код становится более безопасным и понятным. Вам не нужно писать условия, не нужно повторять логику, и код становится более выразительным - сразу видно, что здесь происходит операция типа “получить или вставить”.

    Вот как это выглядит сейчас:

    let prefs = getUserPrefsMap();
    if (!prefs.has("useDarkmode")) {
      prefs.set("useDarkmode", true);
    }
    

    А вот как это будет выглядеть с getOrInsert:

    let prefs = getUserPrefsMap();
    prefs.getOrInsert("useDarkmode", true);
    

    Два способа вставки значений

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

    Разница может показаться незначительной, но для производительности это критично. Представьте, что вычисление значения - дорогостоящая операция: запрос к API, сложные расчёты или работа с большим объёмом данных. Если вы используете обычный getOrInsert с готовым значением, вы всегда создаёте это значение, даже если оно не понадобится. С getOrInsertComputed функция вызывается только если ключ отсутствует.

    Это особенно важно в кешировании, где вы не хотите выполнять вычисления, если данные уже кешированы. Вот практический пример:

    const cache = new Map();
    
    // Плохо - вычисляем всегда
    const result1 = cache.getOrInsert("expensiveKey", computeExpensiveValue());
    
    // Хорошо - вычисляем только если нужно
    const result2 = cache.getOrInsertComputed("expensiveKey", () => computeExpensiveValue());
    

    Методы работают одинаково: они возвращают значение, связанное с ключом. Если ключ уже существует в Map или WeakMap, возвращается старое значение. Если ключа нет, новое значение вставляется и тоже возвращается.

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

    Представьте типичный сценарий: вы собираете статистику пользовательских действий. Когда пользователь совершает действие, нужно увеличить счётчик. Если счётчика ещё нет, его нужно создать:

    const userActions = new Map();
    
    // Старый способ
    if (!userActions.has(userId)) {
      userActions.set(userId, 0);
    }
    userActions.set(userId, userActions.get(userId) + 1);
    
    // Новый способ
    const count = userActions.getOrInsert(userId, 0);
    userActions.set(userId, count + 1);
    

    Другой пример - кеширование результатов вычислений:

    const memoCache = new Map();
    
    function fibonacci(n) {
      return memoCache.getOrInsertComputed(n, () => {
        if (n <= 1) return n;
        return fibonacci(n - 1) + fibonacci(n - 2);
      });
    }
    

    Ещё один случай - инициализация вложенных структур данных:

    const userPreferences = new Map();
    
    function addPreference(userId, key, value) {
      const prefs = userPreferences.getOrInsertComputed(userId, () => new Map());
      prefs.set(key, value);
    }
    

    Типичные сценарии использования:

    • Кеширование результатов вычислений с отложенным вычислением
    • Сбор статистики и метрик с автоматической инициализацией счётчиков
    • Управление настройками пользователя с значениями по умолчанию
    • Работа с пулами объектов, где нужна ленивая инициализация
    • Создание групп элементов, где каждой группе нужна коллекция
    • Управление кешами в Service Workers и Background Workers

    Когда это появится в браузерах

    В Chrome 145 getOrInsert и getOrInsertComputed уже реализованы. Ожидается, что эти методы появятся в браузере в начале 2026 года. После этого они должны достичь стадии 4 спецификации (готовность к стандартизации) весной 2026 года.

    Firefox 144 уже получил эту функцию, так что поддержка будет довольно быстрой. Но обычно требуется несколько версий браузеров, чтобы все пользователи обновились. Для production-кода, если нужна поддержка старых браузеров, имеет смысл написать полифил или собственную обёртку.

    Вот как выглядит простой полифил для Map.prototype.getOrInsert:

    if (!Map.prototype.getOrInsert) {
      Map.prototype.getOrInsert = function(key, value) {
        if (this.has(key)) {
          return this.get(key);
        }
        this.set(key, value);
        return value;
      };
    }
    
    if (!Map.prototype.getOrInsertComputed) {
      Map.prototype.getOrInsertComputed = function(key, computeFn) {
        if (this.has(key)) {
          return this.get(key);
        }
        const value = computeFn();
        this.set(key, value);
        return value;
      };
    }
    

    Поддержка в WeakMap

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

    Reality check: в большинстве случаев вы будете использовать обычную Map. WeakMap нужна, только если вы хотите избежать утечек памяти при длительном хранении ссылок на объекты. Типичный пример - хранение приватных данных для экземпляров классов или кеширование информации о DOM-элементах.

    Для WeakMap синтаксис точно такой же:

    const elementMetadata = new WeakMap();
    
    function getElementData(element) {
      return elementMetadata.getOrInsertComputed(element, () => ({
        created: Date.now(),
        visits: 0
      }));
    }
    

    Интеграция с другими улучшениями

    getOrInsert - это не единственное улучшение для работы с данными в Chrome 145. Одновременно с этим добавлены методы для работы с Uint8Array - fromBase64 и fromHex, которые упрощают преобразования между форматами.

    Также улучшена работа с интернационализацией через Intl.Locale, где теперь доступны более гибкие способы работы с локалями и параметрами нумерации. Всё это вместе создаёт экосистему, где работать с данными становится удобнее.

    Добавлены и другие полезные методы - Iterator.zip() для объединения массивов, улучшенный API Origin для работы с веб-источниками. Это часть общего тренда на удобство разработки и исправление давних болевых точек в языке.

    Что стоит помнить

    Новые методы getOrInsert и getOrInsertComputed - это не революция, а эволюция удобства разработки. Код становится короче, понятнее и менее подвержен ошибкам. Всё это накапливается: малые улучшения в разных местах языка постепенно создают лучший опыт.

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

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

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

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

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

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

    Категории

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

    Контакты

    • Сотрудничество
    • info@exlends.com
    • Наш чат
    • Наш ТГ канал

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

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

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

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