The put/call/takeLatest/takeEvery effects, coupled with all the yields made things impossible to grok for the less seasoned folks. Even for me, having seen some similar things before with other libraries in other languages, it's just not a pattern that my brain wraps itself easily around. There is so much indirection between the sagas and reducers and the effects. Like, I just want to see the code that actually does all the work. I understand the sagas "look" easy, but that's just because all the good stuff is hidden away. I like to see easily where the rubber meets the road, so to speak.
The main selling point was "look how easy this code is to read, it's async but you can read it procedurally". This is mostly true for simple sagas, but the advanced flows were challenging to read, especially trying to remember what each effect did, and what "real" code it called under the covers.
Thinking back on that code, had async/await been used - it would have been simpler to work on and understand, and you wouldn't have carried the weight of a third party library with somewhat esoteric ergonomics.
Edit: It's been several months since I worked on that code, and it's all Angular 2,4,a billion all the time now, so I apologize for limited specifics. In general I appreciate that people are trying new async things (CSP, sagas, observables etc) but they all just feel like a fad to me. Obviously use the right tool for the job, but most of the time I think promises should be the way to go unless there's a super compelling reason not to.
My gripe about sagas is that it mostly reimplement observables-like APIs on top of generators. Observables do take a bit to learn, but once you learnt them, the knowledge is more or less reusable across platforms (even if it's a little different, you can do Go, Scala/Akka, Elixir, and any language that has an Rx implementation).
With Sagas, while the upfront cost and the gain are in the same ballpark for Redux apps, that's basically the only place you'll use the investment. You also cannot leverage the collective knowledge and patterns of the tens of thousands of engineers from other platforms.
That makes it a lot less palatable to me, even though they are easier on the eyes at first, especially for people with mostly procedural programming backgrounds (which is the more common case).
Unlike the initial statement, I do think they're easier to test than even Observables/Promises, because generators make it so easy to inject results and dependencies anywhere in a complex flow. But marble tests aren't bad either.
> There is so much indirection between the sagas and reducers and the effects. Like, I just want to see the code that actually does all the work. I understand the sagas "look" easy, but that's just because all the good stuff is hidden away. I like to see easily where the rubber meets the road, so to speak.
So do I, which is why I dug into it a bit deeper before using it on a project. This article is actually the third in a series (see [1] and [2]), and the first one goes into a little bit of detail about how things work behind the scenes.
> The put/call/takeLatest/takeEvery effects, coupled with all the yields made things impossible to grok for the less seasoned folks.
I definitely feel you on this, and it's _very_ easy to let things get out of hand. I'm very much _not_ a fan of nesting an anonymous generator function inside takeEvery/takeLatest; it's just too easy to start accessing variables from the enclosing scope and then everything gets totally FUBARed.
> It's been several months since I worked on that code, and it's all Angular 2,4,a billion all the time now, so I apologize for limited specifics. In general I appreciate that people are trying new async things (CSP, sagas, observables etc) but they all just feel like a fad to me. Obviously use the right tool for the job, but most of the time I think promises should be the way to go unless there's a super compelling reason not to.
This is totally fair, and I definitely agree that apps should start with simple tools and only use power tools when they're called for. As I mentioned in my other comment, we started out with something like Promises, and moved to redux-saga when that approach was starting to get cumbersome.
The main selling point was "look how easy this code is to read, it's async but you can read it procedurally". This is mostly true for simple sagas, but the advanced flows were challenging to read, especially trying to remember what each effect did, and what "real" code it called under the covers.
Thinking back on that code, had async/await been used - it would have been simpler to work on and understand, and you wouldn't have carried the weight of a third party library with somewhat esoteric ergonomics.
Edit: It's been several months since I worked on that code, and it's all Angular 2,4,a billion all the time now, so I apologize for limited specifics. In general I appreciate that people are trying new async things (CSP, sagas, observables etc) but they all just feel like a fad to me. Obviously use the right tool for the job, but most of the time I think promises should be the way to go unless there's a super compelling reason not to.