Рубрики
Без рубрики

Когда использовать React Supense VS React Cloots

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

Автор оригинала: FreeCodeCamp Community Member.

Преодоление реагирования в монаде в качестве крючков до примеряющих обозначающих

Монады и аппликативные функторы широко используются в функциональном программировании. Существует взаимосвязь между ними и преодолеть преодоления для получения данных и реактивных крючков API. Это быстрое и простое введение в монад и укладки вместе с описанием их сходства.

Почта о будущем реагировать неизвестность к получению данных, а не о недавнем выпуске реагированной прессущения для расщепления кода ( Rect.Suspense и Rect.Lazy ).

Монадская обозначение

Подход Adction Framework побуждает разработчикам использовать функциональные методы программирования. По крайней мере, функции рендеринга компонента не должны иметь наблюдаемые побочные эффекты. У JavaScript нет способа обеспечить это, но есть языки программирования, которые могут. Например, Haskell вообще не принимает побочные эффекты.

Чистые функции делают код модульной, предсказуемым и проще проверить. Но они также значительно повышают многообразие. Вот утверждение от Фил Уолдер ‘s Монады для функционального программирования (1995) Учебник:

Монады решают эту проблему для HASKELL. И ожидание/крючки решают такую же проблему в реакции.

Так что же является монадом? Это простой абстрактный интерфейс, который имеет две функции, давайте назовем их и цепь Отказ

  • – принимает любое значение и возвращает некоторую монадическую (эффективное) значение
  • цепь – принимает эффективное значение и функцию от любого значения эффекту и возвращает другое эффективное значение

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

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

Но зачем нам это понадобиться, если это так абстрактно и не почти ничего не определяет? Интерфейс предоставляет абстрактное означает составить вычисления с побочными эффектами.

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

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

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

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

JavaScript – это обязательный язык. Мы можем рассмотреть любой императивный код уже обозначением. Но в отличие от того, что в Хаскелла, это не абстрактно. Работает только для встроенных побочных эффектов. Нет способа добавить поддержку любого нового, за исключением расширения языка.

Существуют такие расширения, а именно генераторы, Async и Async-генераторные функции. JAVASCIPT JIT Compiler преобразует функции Async и Generator в конкретные встроенные вызовы API. Haskell не нуждается в таких расширениях. Его компилятор преобразует обозначение в абстрактные вызовы функций интерфейса Monads.

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

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

Мы можем преобразовать некоторые эффекты в других. Таким образом, мы можем написать ASYNC код с использованием генераторов.

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

Когда код встречается некоторая эффективная операция и требует подвески, она бросает исключение. Он содержит некоторые детали (например, объект обещания). Одним из его абонентов охватывает исключение, ожидает, что обещание в аргументе урегулировано, сохраняет полученное значение в кэше и повторно запускает эффективную функцию с самого начала.

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

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

/** effectful expression throws this object if it requires suspension */
const token = {};

/** Pointer to mutable data used to record effectful computations */
let context;

/** Runs `thunk()` as an effectful expression with `of` and `chain` as Monad's definition */
const run = (of, chain) => thunk => {
  /** here it caches effects requests */
  const trace = [];
  const ctx = {trace};
  return step();
  function step() {
    const savedContext = context;
    ctx.pos = 0;
    try {
      context = ctx;
      return of(thunk());
    } catch(e) {
      /** re-throwing other exceptions */
      if (e !== token)
        throw e;
      const {pos} = ctx;
      return chain(ctx.effect,
                   (value) => {
                     trace.length = pos;
                     /* recording the resolved value */
                     trace[pos] = value;
                     ctx.pos = pos + 1;
                     /** replay */
                     return step(value);
                   })
    } finally {
      context = savedContext;
    }
  }
}

/** marks effectful expression */
const M = eff => {
  /* if the execution is in a replay stage the value will be cached */
  if (context.pos < context.trace.length)
    return context.trace[context.pos++];
  /* saving the expression to resolve in `run` */
  context.effect = eff;
  throw token;
}

Теперь давайте добавим конкретную реализацию Async Effects. Обещания, к сожалению, не совсем не монады, так как один законодательство монады не оставляют их, и это является источником тонких проблем, но они все еще в порядке для нашей обозначения на работу.

Вот конкретный асинхронный эффект реализации:

const runPromise = run(
  v => Promise.resolve(v), 
  (arg, f) => arg.then(f));

И вот простой пример, он ожидает задержанных значений перед рендерингом:

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

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

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

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

const runCont = run(
  value => cont => cont(value),
  (arg, next) => cont => arg(value => next(value)(cont)));

const useState = initial =>
  M(cont => 
    cont([initial, function next(value) { cont([value,next]); }]));

И вот пример рабочего использования, с большинством копирования «Kit.js», кроме определения монады.

К сожалению, это не совсем Уместите Крюк из реагирования пока, и следующий раздел показывает, почему.

Применительную запись

Есть еще одно расширение для обозначения в Haskell. Это нацелен на не только монадские абстрактные интерфейсные звонки, но также называет абстрактный интерфейс Applicative Functors.

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

Я использую другой из интерфейса Haskell. Оба равны, хотя – просто преобразовать интерфейс HASKELL в тот, который используется здесь и обратно. Я делаю это, потому что эта основа намного проще использовать в JavaScript, ему не нужно никаких функций высшего порядка, и уже есть его экземпляр в стандартной среде выполнения.

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

Если есть реализация по умолчанию, почему нам нужны аппликативные функторы? Есть две причины. Первый не все заявительные функторы – это монады, поэтому нет цепь Метод, от которого мы можем генерировать Присоединяйтесь к Отказ Еще одна причина, даже если есть цепь , на заказ Присоединяйтесь к Реализация может сделать то же самое по-другому, вероятно, более эффективно. Например, привлечь ресурсы параллельно, а не последовательно.

Существует экземпляр этого интерфейса для обещаний в стандартной среде выполнения. Это Обещание. Все (игнорируя некоторые детали здесь для простоты).

Давайте теперь вернемся к примеру государства. Что если мы добавим другой счетчик в компоненте?

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

Это происходит потому, что каждая продолжение вызывания стирает все после него в коде. Когда первый счетчик изменяет свое значение, все следующее продолжение повторно запускается с самого начала. И там вторая счетчик счетчика снова 0.

В Запустите функцию реализации Недействительные случаются в строке 26 – Trace.length – Это удаляет все запоминающиеся значения после текущего (в POS ). Вместо этого мы могли бы попытаться развлечь/исправить трассировку вместо этого. Это был бы пример адаптивного монады, используемого для дополнительных вычислений. MobX и подобные библиотеки очень похожи на это.

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

Транспортер альтернатива

Использование крючков уже производит программы более сжатыми, многоразовыми и читаемыми. Представьте себе, что вы могли бы сделать, если бы не было ограничений (правила крючков). Ограничения обусловлены только встраиванию только во время выполнения. Мы можем удалить эти ограничения с помощью транспортировщика.

Creatual.js это транспортер для встраивания эффектирован в Javancip. Он поддерживает как монадические, так и примеряющие цели. Это значительно упрощает программы в проектировании, реализации, тестировании и поддержании этапов.

В отличие от реактивных крюков и неизвестности, транспортер не должен следовать любым правилам. Он работает для любого оператора JavaScript (ветви, петли, исключения и т. Д.). Это никогда не воспроизводит функции с самого начала. Это быстрее. Кроме того, функции могут использовать любой встроенный побочный эффект JavaScript.

Creatual.js не совсем транспортер, а скорее инструмент для создания транспортировщиков. Есть также несколько предопределенных и много вариантов настройки. Он поддерживает синтаксис двойного уровня со специальными маркерами для эффективных значений (например, a ждать выражения в асинхронных функциях, или do haskell’s do). И он также поддерживает синтаксис одного уровня, в котором эта информация неявная (например, ожидания, крючки или языки с алгебраическими эффектами).

Я быстро построил подобный крючком транспортелю для демо-целей – @ Эффективное/React-Do Отказ Вызов функции с именами, начиная с «использования», считается эффективным. Функции трансформируются только в том случае, если их имя начинается с «использования», или у них есть «компонент» или «Эффективная» Директива Block (строка в начале функции).

Существует также «PAR» и «SEQ» директивы на уровне блока для переключения между примеряющими и монадическими целями. С помощью режима «PAR» включен компилятор, анализируют переменные зависимости и впрыскивания Присоединяйтесь к вместо цепь если возможно.

Вот пример с двумя счетчиками, но теперь адаптированы с транспортом:

Для демонстрационных целей он также реализует неизвестность к расщеплению кода. Вся функция длина шесть строк. Проверьте это в реализации времени выполнения @ Эффективный/React-Do/Main.js Отказ В следующем примере я добавил другой счетчик, какую рендеринг искусственно задерживается для демонстрационных целей.

Алгебраические эффекты

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

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

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

Призывая продолжение также удается все после соответствующего бросить Отказ Существует также специальные правила синтаксиса и набора текста для получения аппликации (и стрелки) API – Алгебраические эффекты и эффекты обработчики для идиом и стрел Отказ Unline Applative-Do запрещает использование любого, что требует монадских операций.

Обертывание

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

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

В качестве примера, Efformated.js может заменить неизвестность, крючки, контекст и состояние компонентов с крошечными функциями. Границы ошибок являются обычными попробовать заявления. Async Renseering – асинхронный планировщик. Но мы можем использовать его для любых вычислений, не только для рендеринга.

Есть много других потрясающих применений, и я скоро пишу больше о них. Оставайтесь в курсе!