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

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

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

5 ответов


отказ от ответственности: я один из авторов redux-observable, поэтому мне трудно быть 100% беспристрастным.

в настоящее время мы не предоставляем никаких причин, по которым redux-observable лучше, чем redux-saga, потому что...это не так.

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

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

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

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

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

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

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

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


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

  1. сложности
  2. Кодирование Стиле
  3. Обучение
  4. Контролепригодность

допустим, мы хотим получить пользователя из 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-saga и Redux-Observable в глубине. Проверьте эта ссылка здесь или презентация.


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

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

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

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


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


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

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

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

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

Если у вас нет предварительного знания наблюдаемого, это будет боль для вас, и ваша команда будет курс вас:)

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

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

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

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

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

http://reactivex.io/languages.html

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

Так тратить свое время мудро узнать RxJS и использовать redux-observable:)