DevGang
Авторизоваться

Исследование Effect, фреймворка метасостояний, подобного RxJS.

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

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

Что такое Effect?

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

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

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

Реактивный характер Effect позволяет вам динамически реагировать на такие события, как доступность нового контента или взаимодействие с пользователем, что делает платформу потоковой передачи более отзывчивой и интерактивной.

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

Зачем использовать Effect?

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

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

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

type Effect<Requirements, Error, Value> = (
  context: Context<Requirements>,
) => Error | Value;

Тип Effect принимает три параметра:

  • Требования: данные, которые должен выполнять эффект, которые хранятся в коллекции контекстов. Вы также можете передать «никогда» в качестве параметра типа, если эффект не имеет требований.
  • Ошибка: Любые ошибки, которые могут возникнуть во время выполнения. Вы также можете выбрать «передавать никогда», чтобы указать, что эффект никогда не будет неудачным.
  • Значение: представляет собой ценность успеха эффекта. Здесь вы можете передать void, никогда или точный тип значения, который вы ожидаете. Если вы передадите void, то значение успеха не будет содержать полезной информации. Если вы введете «никогда», эффект будет действовать вечно.

Ниже приведен пример типа Effect:

function divide(a: number, b: number): Effect.Effect<never, Error, number> {
  if (b === 0) {
    return Effect.fail(new Error("Cannot divide by zero"));
  }

  return Effect.succeed(a / b);
}

В приведенном выше блоке кода у нас есть функция деления, которая подписывается на шаблон Эффекта.

Мы не передали параметр Requirements, тип Error в параметре Error и номер типа в параметре Value. Это означает, что этот Effect не принимает никаких требований, может завершиться неудачей с ошибкой типа Error, если второе число равно нулю, и завершиться успешно с успешным значением типа Number.

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

Однако что происходит, когда мы пишем код, но забываем использовать блок try...catch или выбрасываем исключение? Взгляните на пример ниже:

const getData = () => {
  const response = await fetch("fetch someething from a random API");
  const parseResponse = await response.json();
  return dataSchema.parse(parseResponse);
};

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

Итак, как нам исправить приведенный выше код с помощью библиотеки эффектов? Давайте посмотрим:

import { Effect, pipe } from "effect";

const getData = (): Effect.Effect<never, Error, Data> => {
  return pipe(
    Effect.tryPromise({
      try: () => fetch("fetch something from a random API"),
      catch: () => new Error("Fetch returned an error"),
    }),

    Effect.flatMap((res) =>
      Effect.tryPromise({
        try: () => res.json(),
        catch: () => new Error("JSON parse cant be trusted also😭"),
      }),
    ),

    Effect.flatMap((json) =>
      Effect.try({
        try: () => dataSchema.parse(json),
        catch: () => new Error("This error is from the data schema"),
      }),
    ),
  );
};

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

Этот код показывает реальный пример использования Effect. Если вы посмотрите на блок кода без типа Effect, мы увидим, что функция обрабатывает три операции: выборку данных, анализ JSON и анализ dataSchema.

В примере с Effect мы создали тип Effect<never, Error, Data> в третьей строке. Теперь, если у вас есть разные обработчики ошибок для каждой конкретной операции, вы можете переписать Эффект, чтобы использовать эти обработчики ошибок, следующим образом:

type Effect<never, FetchError | JSONError | DataSchemaError, Data>

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

Следует признать, что приведенное выше решение более подробное, чем, скажем, использование блока try...catch для переноса всей функции и выдачи исключения. Несмотря на это, Effect гарантирует, что каждая ошибка обрабатывается особым образом, что упрощает отладку вашего кода.

Особенности эффекта

До сих пор мы видели, как использовать библиотеку Effect для создания и составления чисто функциональных программ на TypeScript. Теперь давайте посмотрим на некоторые из его выдающихся особенностей:

  • Параллелизм: Effect предлагает возможности для параллельного программирования за счет использования волокон, которые представляют собой легкие потоки выполнения, которые мы можем планировать независимо, обеспечивая эффективный и масштабируемый параллелизм.
  • Обработка ошибок: Эффект реализует надежный механизм обработки ошибок с использованием функциональных конструкций. Сюда входит тип данных «Либо» для явной обработки ошибок и возможность определять каналы ошибок внутри эффектов.
  • Управление ресурсами: Эффект обеспечивает структурированный подход к управлению ресурсами. Библиотека обеспечивает безопасное получение и освобождение ресурсов, предотвращая утечку ресурсов и улучшая управление ресурсами.
  • Компонуемость: Эффект подчеркивает возможность компоновки и модульность. Поскольку создавать эффекты легко, вы также можете легко создавать сложные программы из более мелких компонентов многократного использования.
  • Безопасность типов: Effect широко использует систему типов TypeScript для обеспечения строгой безопасности типов. Это помогает обнаружить множество ошибок во время компиляции, снижая вероятность проблем во время выполнения.

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

Плюсы и минусы использования Эффекта

Использование Effect в ваших проектах имеет несколько преимуществ, а также несколько недостатков, о которых следует помнить.

Некоторые из плюсов эффекта включают в себя:

  • Структурированное асинхронное программирование: Эффект представляет структурированный подход к обработке асинхронных операций. Это позволяет разработчикам составлять асинхронный код и управлять им декларативным и функциональным способом.
  • Постепенное внедрение. Дополнительным преимуществом использования библиотеки Effect является то, что ее можно постепенно внедрять в проекты TypeScript, что позволяет разработчикам выбирать, как и если они хотят продолжать использовать библиотеку, не вызывая радикальных изменений в методах разработки.
  • Простота обслуживания и отладки. Использование Effect позволяет легко поддерживать и отлаживать код, поскольку предсказуемый характер кода Effect может способствовать упрощению обслуживания и отладки.

Между тем, некоторые недостатки использования Effect включают в себя:

  • Кривая обучения. Кривая обучения Effect довольно крутая, поскольку Effect вводит концепции функционального программирования в TypeScript, что может стать проблемой для разработчиков, которые с ним не знакомы. Однако, поскольку вы можете постепенно внедрять Effect в свои проекты, вы можете потратить время на то, чтобы узнать, как лучше всего применять эффекты в ваших программах TypeScript.
  • Зрелость экосистемы. Хотя у Effect есть активное сообщество, экосистема может быть не такой зрелой или обширной, как некоторые другие библиотеки или фреймворки. Это может повлиять на доступность документации, сторонних библиотек и ресурсов.

Важно учитывать эти факторы, прежде чем решать, использовать ли Effect в ваших проектах TypeScript.

Чем Effect отличается от RxJS?

RxJS — это библиотека для реактивного программирования с использованием Observables, которая представляет собой мощный и универсальный способ управления асинхронным программированием и программированием на основе событий. RxJS основан на парадигме реактивного программирования, которая использует наблюдаемые, наблюдатели и субъекты для обработки событий.

Итак, чем RxJS отличается от Effect? Ниже приведена таблица, в которой сравниваются возможности RxJS и Effect:

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

  • Выберите библиотеку, которая соответствует потребностям вашего проекта
  • Выбирайте «Эффект», когда строгая типобезопасность, компонуемость и функциональное программирование являются ключевыми факторами.
  • Выбирайте RxJS для асинхронных и событийно-ориентированных проектов.

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

Заключение

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

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

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

Источник:

#JavaScript #RxJS
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу