Зачем использовать Redux-Observable над Redux-Saga?

Я использовал Redux-Saga. Код, написанный с ним, легко рассуждать до сих пор, за исключением того, что функция генератора JS время от времени испортила мне голову. По моему мнению, Redux-Observable может достичь аналогичного задания, которое обрабатывает побочные эффекты, но без использования функции генератора.

Однако документы из Redux-Observable не дают много мнений о том, почему он превосходит Redux-Saga. Я хотел бы знать, является ли использование функции генератора единственным преимуществом использования Redux-Observable. И какими могут быть недостатки, полученные или компромиссы от использования Redux-Observable вместо Redux-Saga? Спасибо заранее.

Ответ 1

Отказ от ответственности: я являюсь одним из авторов наблюдаемого сокращения, поэтому мне трудно быть на 100% беспристрастным.

В настоящее время мы не предоставляем каких-либо причин, по которым сокращение-наблюдаемое лучше, чем сокращение-сага, потому что... это не так. 😆

tl; dr есть плюсы и минусы для обоих. Многие найдут еще один интуитивный, чем другие, но оба они сложны в том, чтобы учиться по-разному, если вы не знаете RxJS (redux-наблюдаемый) или генераторы / "эффекты как данные" (redux-saga).

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

redux-наблюдаемый отбрасывает почти все до идиоматического RxJS. Поэтому, если у вас есть знание RxJS (или получить его), обучение и использование сокращаемого наблюдаемого супер супер естественно. Это также означает, что это знание может быть передано другим вещам, нежели redux. Если вы решите переключиться на MobX, если вы решите переключиться на Angular2, если вы решите переключиться на некоторую будущую горячность X, шансы очень хорошие, что RxJS может вам помочь. Это связано с тем, что RxJS является общей асинхронной библиотекой и во многом похож на сам язык программирования - целую парадигму "реактивного программирования". RxJS существует с 2012 года и запускается как порт Rx.NET(есть "порты" почти на каждом главном языке, это полезно).

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

Он также использует "эффекты как данные" (описанный здесь), что может быть трудно обернуть вокруг вас сначала, но это означает что ваш код редукции-саги фактически не выполняет сами побочные эффекты. Вместо этого вспомогательные функции, которые вы используете, создают объекты, которые похожи на задачи, которые представляют собой намерение сделать побочный эффект, а затем внутренняя библиотека выполняет его для вас. Это делает тестирование очень простым, без необходимости насмехаться и очень привлекательно для некоторых людей. Тем не менее, я лично нашел, что это означает, что ваши юнит-тесты переопределяют значительную часть вашей логики саги - делая эти тесты не очень полезными ИМО (это мнение не разделяют все)

Люди часто спрашивают, почему мы не делаем что-то подобное с наблюдаемым снижением: для меня это принципиально несовместимо с нормальным идиоматическим Rx. В Rx мы используем такие операторы, как .debounceTime(), который инкапсулирует логику, требуемую для debounce, но это означает, что если мы хотим сделать версию, которая фактически не выполняет debouncing, а вместо этого испускает объекты задачи с намерением, вы теперь потерял силу Rx, потому что вы не можете просто просто переводить операторов, потому что они будут работать на этом объекте задачи, а не на реальном результате операции. Это очень сложно объяснить элегантно. Это снова требует глубокого понимания Rx, чтобы понять несовместимость подходов. Если вы действительно хотите что-то подобное, посмотрите redux-cycles, который использует cycle.js и в основном имеет эти цели. Я считаю, что это требует слишком много церемоний для моих вкусов, но я призываю вас дать ему шанс, если он вас интересует.

Как упоминал ThorbenA, я не уклоняюсь от признания того, что в настоящее время редукционная сага (10/13/16) является явным лидером в области комплексного управления побочными эффектами для сокращения. Он был начат ранее и имеет более надежное сообщество. Таким образом, есть много привлекательности для использования де-факто стандарта над новым ребенком на блоке. Я думаю, что можно с уверенностью сказать, что если вы используете либо без предварительного знания, вы можете столкнуться с некоторой путаницей. Мы используем довольно продвинутые концепции, которые, как только вы "получаете", упрощают управление сложными побочными эффектами, но до тех пор многие спотыкаются.

Самый важный совет, который я могу дать, - не доводить ни одну из этих библиотек до того, как они вам понадобятся. Если вы делаете простые айакс-звонки, вы, вероятно, не нуждаетесь в них. redux-thunk - это глупость, простое в освоении и обеспечивающее достаточно для основ - но чем сложнее асинхронно, тем сложнее (или даже невозможным) оно становится для redux-thunk. Но для redux-наблюдаемых/сага во многих отношениях он наиболее сияет, чем сложнее асинхронный. Кроме того, есть много преимуществ в использовании редукта с одним из других (redux-observable/saga) в том же проекте! redux-thunk для ваших простых простых вещей, а затем только с использованием сокращаемой наблюдаемой/саги для сложных вещей. Это отличный способ оставаться продуктивным, поэтому вы не сражаетесь с редукцией-наблюдаемой/сагой для вещей, которые были бы тривиальны с сокращением.

Ответ 2

Я думаю, что есть вещи, которые вам нужно принимать во внимание.

  • Сложность
  • Стиль кодирования
  • Кривая обучения
  • Тестируемость

Предположим, мы хотим получить пользователя из API

// Redux-Saga

import axios from 'axios' 

function* watchSaga(){
  yield takeEvery('fetch_user', fetchUser) // waiting for action (fetch_user)
}

function* fetchUser(action){
    try {
        yield put({type:'fetch_user_ing'})
        const response = yield call(axios.get,'/api/users/1')
        yield put({type:'fetch_user_done',user:response.data})
  } catch (error) {
        yield put({type:'fetch_user_error',error})
  }
}

// Redux-Observable
import axios from 'axios'

const fetchUserEpic = action$ => 
    action$
        .ofType('fetch_user')
        .flatMap(()=>
          Observable.from(axios.get('/api/users/1')) // or use Observable.ajax
            .map(response=>({type:'fetch_user_done', user:response.data}))
            .catch(error => Observable.of({type:'fetch_user_error',error}))
            .startWith({type:'fetch_user_ing'})
        )

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

Ответ 3

Я использую Redux-Observable над Redux-Saga, потому что предпочитаю работать с наблюдаемыми над генераторами. Я использую его с RXJS, который является мощной библиотекой для работы с потоками данных. Подумайте об этом, как lodash для async. С точки зрения любых недостатков, получения и компромиссов при выборе одного над другим, посмотрите этот ответ от Jay Phelps:

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

Счётчик, заключающийся в том, что операторы и API, которые вы изучаете в саунд-релизе, не так переносимы, как обучение RxJS, которое используется повсеместно. redux-observable супер супер супер просто внутренне, это действительно просто дает вам естественный способ использовать RxJS. Поэтому, если вы знаете RxJS (или хотите), это очень естественная подгонка.

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

Ответ 4

Я ценю переносимость между языками и временем выполнения, которое имеет Rx. Даже если ваше приложение не изменит языки, ваша карьера может. Получите лучшее пособие, которое вы можете получить в своем обучении, но вы сами это оцениваете. Это отличный выход в .Net LINQ, в частности.

Ответ 5

Redux-Observable - это удивительная библиотека, мы используем ее на производстве уже 1,5 года без каких-либо проблем, она отлично тестируется и может быть легко интегрирована с любой средой. У нас чрезвычайно перегружены параллельные каналы сокетов, и единственное, что спасает нас от зависаний, это Redux-Observable

У меня есть 3 очка, которые я хотел бы упомянуть здесь.

1. Сложность и кривая обучения

Redux-сага легко превосходит наблюдаемую здесь редуксу. Если вам нужен простой запрос для выполнения авторизации и по каким-либо причинам вы не хотите использовать redux-thunk, вам следует рассмотреть возможность использования redux-saga, это проще понять.

Если у вас нет предварительных знаний о Observable, вам будет больно, и ваша команда обучит вас :)

2. Что мне могут предложить Observable и RxJS?

Когда речь заходит об асинхронной логике, Observable - это ваш швейцарский нож, Observable может буквально сделать практически все для вас. Вы никогда не должны сравнивать их с обещаниями или генераторами, которые гораздо мощнее, так же, как сравнивать Optimus Prime с Chevrolet.

А как насчет RxJS? Это похоже на lodash.js, но для асинхронной логики, когда вы внутри, вы никогда не переключитесь на что-то другое.

3. Реактивное расширение

Просто проверьте эту ссылку

http://reactivex.io/languages.html

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

Так что тратьте свое время с умом изучать RxJS и использовать наблюдаемые излишки :)

Ответ 6

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

Для чего это стоит, я использую саги в производстве в веб-приложении.

Саги против Thunk

Сага побеждает руки вниз. Мне не понравилось, как громко вкладывает логику в моих создателей действий. Это также сделало выполнение нескольких запросов подряд хлопотным. Я кратко посмотрел на наблюдаемую для этой работы избыточность, но остановился на Sagas.

Кривая обучения для саг

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

Основные методы саги (по моему опыту):

  • call - call любой бит кода и получить возвращаемое значение. Поддерживает обещания. Отличная синергия между асинхронной обработкой и сагами.
  • select - вызов селектора. Этот бит довольно блестящий. Селекторы являются ядром для редукса, и они поддерживаются на 100%!
  • put - иначе dispatch действие. На самом деле отправить столько, сколько вы хотите!

Есть и другие функции, но если вы справитесь с этими тремя, вы окажетесь в действительно хорошем месте.

Заключение

Причиной, по которой я выбрал сагу, была простота использования. наблюдаемая редукса выглядела как вызов. Я доволен сагами на 100%. Счастливее, чем я ожидал.

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

Ответ 7

Если вы пишете свое приложение на Typescript, я рекомендую проверить без типа. Он вдохновлен Redux-Observable, а также зависит от RxJS, но есть целая экосистема для создания приложения.

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

Несимметричные плюсы:

  1. Разработано для TypeScript
    Все API разработаны для машинописи и безопасности типов:
    • Typescript повысит вашу производительность, а не замедляет работу.
    • Требуются только необходимые аннотации: состояние, аргументы действия.
    • Нет доработки. Все выводится автоматически. 95% кода выглядит как чистый JavaScript.
    • Нет RootAction, RootEpic, RootState или других вспомогательных типов.
  2. Предоставить все строительные блоки
    • Typeless включает в себя все для создания приложений среднего или корпоративного уровня.
    • Вам не нужно полагаться на несколько небольших библиотек.
  3. Модульность
    • Правильная модульность имеет решающее значение для создания масштабируемых приложений.
    • Нет необходимости создавать корневые файлы для эпосов, редукторов, типов и т.д. После создания нового модуля его можно прикрепить из любого места. Аналогично стандартным компонентам React.
  4. Самоуверенный
    • Все распространенные варианты использования и проблемы решаются по умолчанию. Не нужно переосмысливать, как исправить тривиальные проблемы.
    • Все рекомендации и лучшие практики предоставляются!

Проверять, выписываться https://typeless.js.org/