Перейти к содержимому

Что такое идемпотентность в программировании

  • автор:

Идемпотентный метод

Метод HTTP является идемпотентным, если повторный идентичный запрос, сделанный один или несколько раз подряд, имеет один и тот же эффект, не изменяющий состояние сервера. Другими словами, идемпотентный метод не должен иметь никаких побочных эффектов (side-effects), кроме сбора статистики или подобных операций. Корректно реализованные методы GET , HEAD , PUT и DELETE идемпотентны, но не метод POST . Также все безопасные методы являются идемпотентными.

Для идемпотентности нужно рассматривать только изменение фактического внутреннего состояния сервера, а возвращаемые запросами коды статуса могут отличаться: первый вызов DELETE вернёт код 200 , в то время как последующие вызовы вернут код 404 . Из идемпотентности DELETE неявно следует, что разработчики не должны использовать метод DELETE при реализации RESTful API с функциональностью удалить последнюю запись.

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

GET /pageX HTTP/1.1 идемпотентен. Вызвавший несколько раз подряд этот запрос, клиент получит тот же результат:

GET /pageX HTTP/1.1 GET /pageX HTTP/1.1 GET /pageX HTTP/1.1 GET /pageX HTTP/1.1

POST /add_row HTTP/1.1 не идемпотентен; если его вызвать несколько раз, то он добавит несколько строк:

POST /add_row HTTP/1.1 POST /add_row HTTP/1.1 -> Adds a 2nd row POST /add_row HTTP/1.1 -> Adds a 3rd row

DELETE /idX/delete HTTP/1.1 идемпотентен, даже если возвращаемый код отличается:

DELETE /idX/delete HTTP/1.1 -> Returns 200 if idX exists DELETE /idX/delete HTTP/1.1 -> Returns 404 as it just got deleted DELETE /idX/delete HTTP/1.1 -> Returns 404

Материалы для изучения

Общие

  • Определение идемпотентности в спецификации HTTP.

Технические

  • Описание общих идемпотентных методов: GET , HEAD , PUT , DELETE , OPTIONS
  • Описание общих неидемпотентных методов: POST

Found a content problem with this page?

  • Edit the page on GitHub.
  • Report the content issue.
  • View the source on GitHub.

This page was last modified on 12 нояб. 2023 г. by MDN contributors.

Your blueprint for a better internet.

MDN

Support

  • Product help
  • Report an issue

Our communities

Developers

  • Web Technologies
  • Learn Web Development
  • MDN Plus
  • Hacks Blog
  • Website Privacy Notice
  • Cookies
  • Legal
  • Community Participation Guidelines

Visit Mozilla Corporation’s not-for-profit parent, the Mozilla Foundation.
Portions of this content are ©1998– 2024 by individual mozilla.org contributors. Content available under a Creative Commons license.

Что такое Идемпотентность

Идемпотентность — это свойство некоторых операций, которое означает, что повторное выполнение операции не приводит к изменению состояния системы или ресурса.

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

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

Примеры идемпотентности

Вот несколько примеров идемпотентных операций:

  1. HTTP GET запрос: HTTP метод GET является идемпотентным, потому что он используется для получения данных с сервера. Повторные GET запросы к одному и тому же ресурсу не должны изменять состояние сервера или данных на нем.
  2. HTTP DELETE запрос: HTTP метод DELETE также является идемпотентным, поскольку он используется для удаления ресурсов с сервера. Если вы отправите DELETE запрос на удаление ресурса, повторное выполнение этого запроса не изменит состояния сервера.
  3. Обновление записи в базе данных: Предположим, у вас есть операция обновления записи в базе данных с использованием SQL-запроса типа UPDATE. Если этот запрос написан так, чтобы он изменял запись только один раз, то он будет идемпотентным. Повторное выполнение этого запроса не приведет к дополнительным изменениям в базе данных.
  4. Операции счета в банковской системе: Перевод денег с одного счета на другой может быть идемпотентным, если система гарантирует, что повторное выполнение операции не приведет к дополнительным переводам. Это важно для предотвращения двойных списаний или переводов. Даже если клиентское приложение отправит запрос на вычитание несколько раз, баланс счета не изменится более чем на запрашиваемую сумму.
  5. Операции создания и удаления файла: Создание и удаление файлов на файловой системе может быть идемпотентным, если повторное выполнение операции не приводит к созданию дополнительных файлов или удалению уже удаленных файлов.

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

Идемпотентность

Недостатки идемпотентности

Идемпотентность является важным и полезным свойством в программировании и сетевой архитектуре, но, как и всякая концепция, она имеет свои недостатки и ограничения:

Сложность реализации: Реализация идемпотентных операций может быть сложнее и требовать больше усилий по сравнению с неидемпотентными операциями. Это может привести к дополнительным затратам времени и ресурсов на разработку и тестирование.

Ограничения функциональности: Идемпотентность может ограничивать некоторые операции, особенно те, которые должны привести к изменению состояния каждый раз при выполнении. В таких случаях неидемпотентные операции могут быть необходимы.

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

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

Повышенное потребление ресурсов: Некоторые идемпотентные операции могут потреблять больше ресурсов (например, памяти или процессорного времени) из-за необходимости отслеживания состояния или проверки, была ли операция уже выполнена.

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

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

Дополнительно

  • Стажёр Вася и его истории об идемпотентности API
  • В защиту простых архитектур

Если вы нашли опечатку — выделите ее и нажмите Ctrl + Enter! Для связи с нами вы можете использовать info@apptractor.ru.

Почему важна идемпотентность и как писать идемпотентные bash-скрипты

Почему важна идемпотентность и как писать идемпотентные bash-скрипты главное изображение

Идемпотентность помогает проектировать более надёжные системы. Это математическая концепция, которую должен понимать каждый разработчик. Операция считается идемпотентной, если её многократное выполнение приводит к тому же результату, что и однократное выполнение. Например, умножение на 1 — идемпотентная операция.

  • Идемпотентность HTTP-методов
  • Очереди сообщений
  • Убедитесь в идемпотентности задач, которые выполняете через воркер
  • SQL-миграции
  • Денормализованные данные
  • Как писать идемпотентные bash-скрипты
  • Bash-идиомы
    • Создание пустого файла
    • Создание директории
    • Создание символической ссылки
    • Удаление файла
    • Изменение файла
    • Проверка существования переменной, файла или директории
    • Форматирование устройства
    • Монтирование устройства

    Умножение на ноль — тоже идемпотентная операция.

    Ключевая концепция, которую нужно запомнить: однократное выполнение операции может иметь побочные эффекты, но повторное выполнение этой же операции не приведёт ни к чему другому, кроме того, что было сделано при первом выполнении. То есть присваивание — идемпотентная операция.

    Вы можете присваивать x значение 4 сколько угодно раз, но x всё равно будет иметь значение 4. При этом присваивание x значения 4 один раз отличается от нуля.

    Бесплатные курсы по программированию в Хекслете

    • Освойте азы современных языков программирования
    • Изучите работу с Git и командной строкой
    • Выберите себе профессию или улучшите навыки

    Идемпотентность HTTP-методов

    HTTP-методы могут быть идемпотентными или нет.

    DELETE — идемпотентный метод. Вы можете сколько угодно раз использовать DELETE, но результат будет всегда таким же, как после первого выполнения операции. Например, DELETE /users/4/contacts/3 удаляет контакт с ID 3. Если вы выполните эту же операцию ещё раз, ничего не произойдёт, так как контакт уже удалён.

    GET — тоже идемпотентный метод. Это даже не просто идемпотентный, но ещё и безопасный метод. А безопасные методы можно сравнить с умножением на единицу. Умножать на 1 можно сколько угодно раз, результат всегда будет одинаковым. GET просто получает ресурс. Например, никогда не стоит использовать нормальные ссылки для удаления ресурсов.

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

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

    NB! Правило наименьшего удивления или principle of least astonishment гласит, что результат выполнения операции должен быть очевидным и предсказуемым по названию операции. Полезно ознакомиться со статьями «Именование в программировании» и «Ошибки именования в программировании».

    Очереди сообщений

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

    Это очень распространённый паттерн, и, если вы его ещё не используете, стоит подумать о том, чтобы начать.

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

    Здесь в игру вступает идемпотентность.

    Убедитесь в идемпотентности задач, которые выполняете через воркер

    Вернёмся к примеру с электронными письмами. Вы можете сохранять в базе данных дату отправки письма приглашённому человеку в соответствующем ряду таблицы. Если письмо уже отправлялось, то есть значение в базе данных отличается от NULL, повторно отправлять письмо не нужно. Очень простое решение. Также можно проверять, завершено ли оформление мероприятия. Если оформление не завершено, письмо отправлять не нужно.

    • Убедитесь, что задача готова к исполнению. Если задача не готова к исполнению, ничего делать не надо.
    • Убедитесь, что задача ещё не исполнена. Если она исполнена, ничего не нужно делать.
    • Выполните задачу, занесите дату выполнения или другую информацию в базу данных. Запишите в лог, что задача выполнена. Например, укажите, что приглашение на такое-то мероприятие отправлено такому-то пользователю.
    • Убедитесь, что задачи гранулированные. Нужно отправить пять писем? Запланируйте задачу, которая выполнит пять других задач. Пример кода ниже.
    send_event_emails(event_id) send_event_email_to_invitee(event_id, invitee_id) 

    Увидели, что что-то идёт не так? Можно снова вызвать функцию, которая отправит все приглашения на все мероприятия. Снова проблемы, когда половина писем отправлена? Исправьте проблему и вызовите функцию снова. Достаточно просто выяснить, какие письма не были отправлены. В качестве бонуса: вы можете понять, сколько писем в день рассылается, когда шлётся больше всего писем и так далее.

    Помните, некоторые очереди не гарантируют отправку одного письма один раз. К ним относится Amazon SQS. Поэтому ваши воркеры должны выполнять только идемпотентные задачи.

    SQL-миграции

    Когда вы выполняете SQL-миграции, позаботьтесь об их идемпотентности.

    Например, вам нужно разделить таблицу пользователя на две. Одна таблица будет для пользователей (users), а вторая для деталей, которые не всегда важны (profiles). Вы помещаете внешний ключ user_id в в таблицу profiles. Получаете миграцию, которая берёт каждый ряд в users (SELECT * FROM users) и вставляет ряд с пользовательскими данными в profiles. Запускаете миграцию, но она крашится через час. Это происходит из-за значений NULL, которые вы не учли. Вы исправляете ошибку, снова запускаете миграцию, но вдруг понимаете, что для некоторых пользователей созданы по два профиля.

    Этого можно избежать с помощью идемпотентного решения. Вместо SELECT * FROM users можно выбрать пользователей, у которых ещё нет ряда в profiles. С таким решением миграцию можно запускать сколько угодно раз. В ходе каждого запуска будут обработаны данные тех пользователей, у которых ещё нет профиля. Огромное преимущество этого подхода — вам не нужно останавливать приложение при выполнении миграции. Как только вы готовы развернуть новую версию, в которой используется profiles, можно вызвать функцию, которая обеспечит миграцию новых пользователей. Это не самый лучший пример, так как пользователь во время миграции может изменить какие-то данные в таблице users. Учитывайте этот момент.

    Денормализованные данные

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

    • ID (хэш)
    • Tag (текст тега)
    • document _id (внешний ключ к документу)

    Когда вы добавляете автора в документ, в таблицу tags попадают данные. Когда вы удаляете автора, соответствующий тег удаляется из таблицы.

    Однажды вы замечаете в логах, что время от времени случались ошибки из-за проблемы кодировки символов. Вы фиксите проблему и разворачиваете приложение с обновлённым кодом. Однако видите, что много тегов отсутствует, и их нужно восстанавливать вручную.

    Вместо функции add_tag_for_new_author вам нужно изначально сделать функцию update_tags_for_document. Эта функция не просто добавляет тег автора. Она проверяет документ, перестраивает список тегов и убеждается, что в базу данных попала корректная информация. При таком подходе таблица tags обрабатывается корректным способом: с помощью кэша. Вы можете удалить все ряды из таблицы и запустить update_tags_for_document. Требуется 2 секунды, чтобы обновить теги? Пусть этим занимается воркер, добавьте сообщение в очередь.

    Как писать идемпотентные bash-скрипты

    Иногда случается такое: вы пишете bash-скрипт, запускаете его, но через какое-то время он завершается из-за ошибки. Вы фиксите ошибку в системе и снова запускаете скрипт. Но часть шагов вашего скрипта падает с ошибкой, так как эти шаги уже были выполнены при первом запуске. Чтобы создавать отказоустойчивые системы, нужно писать идемпотентные программы.

    Bash-идиомы

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

    Создание пустого файла

    Это простая задача. Команда touch по умолчанию идемпотентная. Вы можете вызывать её много раз без проблем. Повторный вызов не повлияет на контент файла. Но он изменит время модификации файла. Если вы его используете, будьте осторожны.

    touch example.txt 

    Создание директории

    Никогда не используйте команду mkdir как есть. Применяйте её с флагом -p. Этот флаг гарантирует отсутствие ошибки при запуске mkdir, если директория уже существует.

    mkdir -p mydir 

    Создание символической ссылки

    Для создания символических ссылок используется такая команда:

    ln -s source target 

    Но эта команда генерирует ошибку, если вы повторно вызовите её с существующей целью. Чтобы сделать команду идемпотентной, добавьте флаг -f.

    ln -sf source target 

    Флаг -f удаляет целевой путь перед созданием символической ссылки, поэтому команда всегда будет успешной. Если вы ссылаетесь на директорию, нужно добавить флаг -n. В противном случае повторный вызов создаст символическую ссылку внутри директории.

    mkdir a ln -sf a b ln -sf a b ls a a 

    Для безопасности всегда используйте такую команду:

    ln -sfn source target 

    Удаление файла

    Следующую ниже команду нежелательно использовать для удаления файлов:

    rm example.txt 

    Чтобы команда игнорировала несуществующие файлы, надо использовать флаг -f.

    rm -f example.txt 

    Изменение файла

    Иногда необходимо добавить новую строку в файл, например, /etc/fstab. Нужно убедиться, что повторный запуск скрипта не приводит к добавлению строки ещё раз. Представьте, что используете такой скрипт:

    echo "/dev/sda1 /mnt/dev ext4 defaults 0 0" | sudo tee -a /etc/fstab 

    Если вы запустите скрипт повторно, получите дублирующуюся запись в /etc/fstab. Один из способов сделать скрипт идемпотентным — проверить существование конкретных плейсхолдеров с помощью grep.

    if ! grep -qF "/mnt/dev" /etc/fstab; then echo "/dev/sda1 /mnt/dev ext4 defaults 0 0" | sudo tee -a /etc/fstab fi 

    В данном случае -q обозначает тихий режим, а -F — режим фиксированной строки. Grep в фоновом режиме завершится с ошибкой, если /mnt/dev не существует, поэтому echo не вызовется.

    Проверка существования переменной, файла или директории

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

    echo "complex set of rules" > /etc/conf/foo.txt 

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

    if [ ! -f "/etc/conf/foo.txt" ]; then echo "complex set of rules" > /etc/conf/foo.txt fi 

    В данном случае -f — только пример. Есть много других флагов, в том числе:

    • -d: директория;
    • -z: строка с нулевой длиной;
    • -p: пайп;
    • -x: файл с разрешением на исполнение.

    Например, если вы хотите установить бинарный файл, но только если его ещё не существует, можно использовать флаг -x таким способом:

    # install 1password CLI if ! [ -x "$(command -v op)" ]; then export OP_VERSION="v0.5.6-003" curl -sS -o 1password.zip https://cache.agilebits.com/dist/1P/op/pkg/$OP_VERSION>/op_linux_amd64_$OP_VERSION>.zip unzip 1password.zip op -d /usr/local/bin rm -f 1password.zip fi 

    Это устанавливает файл op в /usr/local/bin. Повторный запуск скрипта не приведёт к повторной установке бинарного файла. В данном случае есть ещё одно преимущество. Вы можете легко обновить бинарный файл. Для этого достаточно удалить его из системы, обновить OP_VERSION env и повторно запустить скрипт. Список флагов и операторов можно получить с помощью man test.

    Форматирование устройства

    Для форматирования можно использовать такую команду:

    mkfs.ext4 "$VOLUME_NAME" 

    Эта команда печатает атрибуты для заданного блока устройства. Соответственно, предварительное добавление значит продолжение форматирования только при ошибке blkid, которая сообщает, что соответствующий том ещё не отформатирован.

    Монтирование устройства

    Попытка монтировать том в существующий каталог может выполняться с помощью такой команды:

    mount -o discard,defaults,noatime "$VOLUME_NAME" "$DATA_DIR" 

    Но если он уже установлен, возникнет ошибка. Можно проверять вывод команды mount. Но есть лучший вариант. Это использование команды mountpoint.

    if ! mountpoint -q "$DATA_DIR"; then mount -o discard,defaults,noatime "$VOLUME_NAME" "$DATA_DIR" fi 

    Эта команда проверяет, является ли файл или каталог точкой монтирования. Флаг -q гарантирует, что она ничего не выводит и завершается в фоновом режиме. Если точка монтирования не существует, команда монтирует устройство.

    Завершение

    Вы узнали о важности идемпотентности, а также познакомились со способами написания идемпотентных скриптов. Многие из предложенных советов и трюков давно известны, но разработчики часто пренебрегают этими возможностями. Некоторые из представленных идиом очень специфичные. К таким относятся монтирование и форматирование. Тем не менее создание идемпотентных программ — выигрышная стратегия в долгосрочной перспективе. Поэтому полезно знать даже специфичные идиомы.

    Адаптированный перевод статей The Importance of Idempotence by Antoine Leclair и How to write idempotent Bash scripts by Fatih Arslan.

    Бесплатные курсы по программированию в Хекслете

    • Освойте азы современных языков программирования
    • Изучите работу с Git и командной строкой
    • Выберите себе профессию или улучшите навыки

    Функциональное программирование в JavaScript

    Основы функционального программирования в JavaScript.

    JavaScript · 24.12.2019 · читать 3 мин �� · Автор: Alexey Myzgin

    • Неизменность (Immutability)
    • Идемпотентность
    • Императивный и декларативный
    • Карринг
    • Частичное применение
    • Запоминание
    • Чистые функции
    • Ссылочная прозрачность
    • Композиция

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

    Неизменность заключается не в изменении состояния, а в копировании старого состояния, изменении новой копии и замене старого состояния новым.

    Неизменяемые объекты проще создавать, тестировать и использовать. Действительно, неизменяемые объекты всегда потокобезопасны. Они помогают избежать временной связи.

    Временная связь — это связь, которая возникает, когда есть два или более члена класса, которые должны быть вызваны в определенном порядке. Использование неизменяемых объектов происходит без побочных эффектов.

    Постоянная структура данных — это структура данных, которая всегда сохраняет свою предыдущую версию при её изменении. Такие структуры данных фактически неизменяемы, так как их операции не обновляют (заметно) структуру на месте, а вместо этого, всегда дают новую обновленную структуру.

    Идемпотентность (Idempotent) — означает предсказуемость, т.е. при одном и том же вводном значении, функция всегда должна возвращать один и тот же результат.

    Императивный и декларативный

    Императивный код — это код, который сообщает компьютеру, что и как делать. Компьютеры хороши с императивными инструкциями. Например: «Пожалуйста, подойди к столу, правой рукой возьми воду, вернись ко мне и дай воды».

    for (let i = 0; i  1000; i++)  console.log(i); >

    Декларативный код — это код, который сообщает компьютеру, что делать и что должно происходить; он не говорит машине, как именно это сделать. Люди хороши в декларативных инструкциях. Например: «Пожалуйста, дай мне эту воду».

    В этом примере мы не указываем, что начальный индекс 0 и что после каждой итерации его нужно увеличивать.

    [1, 2, 3].forEach(i => console.log(i));

    Карринг (curry) — преобразует функцию с несколькими аргументами в серию функций, каждая из которых принимает один аргумент.

    function multiply(a, b, c)  return a *b * c; > function multiply(a)  return (b) =>  return (c) =>  return a * b * c; > > > console.log(multiply(1)(2)(3)); // 6

    Частичное применение (partial application) похоже на карринг — это процесс создания функции с меньшим количеством параметров.

    Также, частичное применение — это применение к функции некоторых аргументов и возврат новой функции, в ожидании остальных аргументов. Примененные аргументы хранятся в замыкании (closure) и остаются доступными для любых из возвращенных функций в будущем, которые частично применены.

    Запоминание (memoization) — особый вид кеширования. Он кеширует возвращаемое значение на основе своих параметров. Таким образом, если параметры совпадают, вместо поиска функции и повторного вычисления возвращаемого значения, выполняется поиск значения. Это может сэкономить ценные вычислительные циклы.

    Чтобы не загрязнять глобальное пространство имен, используем замыкание:

    function memoizedAdd80WithClosure()  let cache = >; return function(n)  if (n in cache)  return cache[n] > else  console.log('симуляция длительного вычисления'); cache[n] = n + 80; return cache[n]; > > > const memoizedAndEnclosedFunction = memoizedAdd80WithClosure(); memoizedAndEnclosedFunction(80) симуляция длительного вычисления 160 memoizedAndEnclosedFunction(80) 160 memoizedAndEnclosedFunction(80) 160
    • чистые функции всегда должны возвращать один и тот же вывод при одинаковом вводе;
    • чистые функции легко тестировать, легко составлять и избегать ошибок;
    • нет побочных эффектов: чистые функции не могут ничего изменить вне их самих.

    Функция с побочным эффектом, изменяет массив вне функции:

    const arr = [1, 2, 3]; const mutateArray = (arr) =>  arr.pop(); > mutateArray(arr); console.log(arr) // [1, 2]

    Та же функциональность, но с чистой функцией (без побочных эффектов, так как создает новый массив с concat() и его же возвращает). Это не влияет ни на что, вне его сферы действия.

    const arr = [1, 2, 3]; const removeLastItem = (arr) =>  const newArr = [].concat(arr); newArr.pop(); return newArr; > removeLastItem(arr); // [1, 2] console.log(arr) // [1, 2, 3]

    Ссылочная прозрачность (referential transparency) — обычно определяется как факт, что выражение в программе может быть заменено его значением (или чем-либо, имеющим то же значение) без изменения результата программы. Это подразумевает, что методы всегда должны возвращать одно и то же значение для данного аргумента, не оказывая никакого другого влияния.

    const add = (x, y) => x + y; add(1, 2); // 3

    При повторном вызове метода add с теми же вводными, можно заменить его на значение 3 .

    Эта концепция важна, так как означает, что когда у нас есть ссылочно-прозрачная функция, она легко поддается кэшированию.

    Композиция — создание сложной функциональности за счет объединения более простых функций.

    const compose = (. fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *