Why use Redux-Observable over Redux-Saga?

I used Redux-Saga . The code written with it is easy to reason until now, except that the JS generator function has spoiled my head from time to time. In my opinion, Redux-Observable can achieve a similar task that handles side effects, but without using the generator function.

However, the documents from the Redux-Observable do not give many opinions on why it is superior to Redux-Saga. I would like to know if using a generator function is the only advantage of using Redux-Observable. And what could be the disadvantages received or the trade-offs of using Redux-Observable instead of Redux-Saga? Thanks in advance.

+118
javascript reactive-programming redux redux-saga redux-observable
Oct 13 '16 at 12:42 on
source share
6 answers

Disclaimer: I am one of the authors of the observed reduction, so it’s hard for me to be 100% impartial.

We do not currently provide any reasons why the contraction-observable is better than the contraction-saga, because ... it is not. 😆

tl; dr there are pros and cons for both. Many will find one more intuitive than the others, but both of them are difficult to learn differently if you do not know RxJS (redux-observable) or generators / "effects as data" (redux-saga).

They solve the same problem in extremely similar ways, but they have some fundamental differences that become really obvious only after you use them enough.

redux-observable drops almost everything to idiomatic RxJS. Therefore, if you have knowledge of RxJS (or get it), learning and using the abbreviated observable is super super natural. It also means that this knowledge can be transferred to other things than redux. If you decide to switch to MobX, if you decide to switch to Angular2, if you decide to switch to some future X hotness, the chances are very good that RxJS can help you. This is due to the fact that RxJS is a common asynchronous library and in many ways is similar to the programming language itself - the whole paradigm of "reactive programming". RxJS has existed since 2012 and starts as an Rx.NET port (there are "ports" in almost every main language, this is useful).

redux-saga provides its time-based operators, so when the knowledge you acquire about generators and handle side effects in this style of process manager can be transferred, the actual operators and usage are not used in any other main library. So a little unsuccessful, but, of course, should not be a deal break.

It also uses “effects as data” ( described here ), which can be difficult to wrap around you at first, but that means your reduction saga code does not actually perform the side effects themselves. Instead, the helper functions that you use create objects that look like tasks that are intended to have a side effect, and then the internal library does it for you. This makes testing very easy, without the need to taunt and is very attractive to some people. However, I personally found that this means that your unit tests override a significant portion of your saga logic - making these tests not very useful IMO (this is not shared by everyone)

People often ask why we are not doing something similar with the observed decrease: for me this is fundamentally incompatible with normal idiomatic Rx. In Rx, we use operators such as .debounceTime() , which encapsulates the logic required for debounce, but that means that if we want to make a version that actually does not debouncing, but instead emits task objects with intent, you are now lost the power of Rx, because you can’t just simply translate the operators, because they will work on this object of the task, and not on the real result of the operation. It is very difficult to explain elegantly. This again requires a deep understanding of Rx in order to understand the incompatibility of the approaches. If you really want something like this, look for redux-cycles , which uses cycle.js and basically has these goals. I believe that it requires too many ceremonies for my tastes, but I urge you to give him a chance if he interests you.

As ThorbenA mentioned, I do not shy away from recognizing that the reducing saga (10/13/16) is currently the clear leader in the comprehensive management of side effects for contraction. It was launched earlier and has a more reliable community. Thus, there is a lot of attraction for using the de facto standard over a new child on the block. I think it is safe to say that if you use either without prior knowledge, you may encounter some confusion. We use fairly advanced concepts that, as soon as you “get”, simplify the management of complex side effects, but until then many stumble.

The most important piece of advice I can give is not to bring any of these libraries before you need them. If you make simple aiax calls, you probably don't need them. redux-thunk is stupid, easy to learn and provides enough for the basics - but the harder asynchronously, the harder (or even impossible) it becomes for redux-thunk. But for redux-observables / saga in many respects, it shines most, the more complicated asynchronous. In addition, there are many advantages to using a redux with one of the others (redux-observable / saga) in the same project! redux-thunk for your simple simple things, and then only using a reducible observable / saga for complex things. This is a great way to stay productive, so you don't fight the reduction-observable / saga for things that are trivial with reduction.

+211
Oct 13 '16 at 5:51 on
source share

I think there are things that you need to take into account.

  • Complexity
  • Coding style
  • Learning curve
  • Testability

Suppose we want to get a user from the 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'}) ) 

In addition, I wrote this article to compare the differences between the Redux saga and the Redux-Observable in depth. Mark this link here or presentation .

+54
Jan 13 '17 at 4:09 on
source share

I use Redux-Observable on Redux-Saga because I prefer to work with observables on generators. I use it with RXJS, which is a powerful library for working with data streams. Think of it like lodash for async. From the point of view of any flaws, getting and compromises when choosing one over the other, see this answer from Jay Phelps:

redux-saga, since the project existed longer than the contracting one, so it is certainly one of the main selling points. You will find more documentation, examples, and probably get a better community to get support.

The counter is that the operators and APIs that you learn in the sound release are not as portable as the RxJS training, which is used universally. redux-observable super super super super simple internally, it really just gives you a natural way to use RxJS. Therefore, if you know RxJS (or want), this is a very natural fit.

My advice at the moment for most people is that if you need to ask which one you should use, you probably should choose the very one itself.

+18
Oct. 13 '16 at 13:35
source share

I appreciate the portability between languages ​​and the runtime that Rx has. Even if your application does not change languages, your career can. Get the best allowance you can get in your training, but you evaluate it yourself. This is a great way to .Net LINQ in particular.

+6
Apr 20 '17 at 3:11
source share

Redux-Observable is an amazing library, we have been using it in production for 1.5 years without any problems, it is well tested and can be easily integrated into any environment. We have extremely overloaded parallel socket channels, and the only thing that saves us from freezes is the Redux-Observable

I have 3 points that I would like to mention here.

1. Difficulty and learning curve

The Redux saga easily surpasses the redux observed here. If you need a simple request to perform authorization, and for some reason you do not want to use redux-thunk, you should consider using redux-saga, this is easier to understand.

If you do not have prior knowledge of Observable, it will hurt and your team will teach you :)

2. What can Observable and RxJS offer me?

When it comes to asynchronous logic, Observable is your Swiss knife, Observable can literally do almost anything for you. You should never compare them with promises or generators that are much more powerful, just like comparing Optimus Prime with Chevrolet.

What about RxJS? This is similar to lodash.js, but for asynchronous logic, when you are inside, you will never switch to something else.

3. Reactive expansion

Just check this link.

http://reactivex.io/languages.html

Reactive extension is implemented for all modern programming languages, it is simply your key to functional programming.

So spend your time wisely learning RxJS and using the observed surplus :)

+6
Jan 25 '18 at 21:37
source share

Since there is a whole bunch of conversations observed in the reduction, I thought that I would tell the saga about the arguments. I do not use Redx-Observable or RxJS, so I can not give a parallel comparison, but I used sagas with great effect.

For what it's worth, I use sagas in production in a web application.

Sagas vs Thunk

Saga wins hands down. I did not like how loudly puts logic into my action creators. It also made doing multiple queries in a row troublesome. I briefly looked at the redundancy observed for this work, but settled on Sagas.

Learning curve for sagas

Understanding what generators are and why they are important is key to understanding sagas. But I emphasize that you do not need to know the generators inside and out. You only need to know that you are giving up control with the yield statement and that the saga will give control back after resolving the asynchronous code. After that, it’s not a little hard to understand what is happening in the saga.

The main methods of the saga (in my experience):

  • call - call any bit of code and get the return value. Maintains promises. Excellent synergy between asynchronous processing and sagas.
  • select - call the selector. This bit is pretty shiny. Selectors are the core for redux, and they are 100% supported!
  • put - otherwise dispatch action. Actually send as much as you want!

There are other features, but if you handle these three, you will find yourself in a really good place.

Conclusion

The reason I chose the saga was the ease of use. The observable redux looked like a challenge. I am 100% satisfied with the sagas. Happier than I expected.

In my experience, sagas (by the way) are better than thunder, and relatively easy to understand. Rx is not every cup of tea. I would highly recommend sagas, not observable by redux, if you are not from this ecosystem and / or do not plan to use Rx in the future.

+2
Feb 05 '19 at 19:19
source share



All Articles