Which one should I use? For more context I use redux-toolkit. Advices to help understand which tool fits better are appreciated
The Redux Styleguide very clearly recommends thunks over slices for most asynchronous logic. If you have very complex and intertwined logic, sagas might make sense, but most applications don't have that kind of logic.
Also, you should probably try out using RTK-Query which would reduce your need for either middleware for asynchronous tasks quite a bit.
Related
I have been reading about sagas, their intent, and their usage. BUT - I have two questions that I'd really like some closure on, and then more of an opinion question.
When using Sagas for a simple api call, the boilerplate seems very excessive. If I had 20 api calls, how is that less wieldy than using thunks? Plus, I keep hearing the idea of "side effects" - but I'm unsure how that plays into it all.
I read some blogs that used a pattern that was able to dynamically generate the Sagas to reduce less boilerplate - but couldn't you do that with thunks too? Also, any examples would be great.
Are Sagas still usefull when literally dealing with very simple post or get calls?
Any opinions on redux-sags vs. redux-observables?
thanks!
Disclaimer: I am one of the authors of redux-observable, so my opinions of both redux-saga and redux-observable are tainted with bias
Since you used the term Saga (instead of Epic) I'll assume you're asking in the context of redux-saga (not redux-observable).
In redux-saga, the effects you do, e.g. an AJAX request, aren't actually directly handled inside your generator sagas. Instead, the helpers you use are creating Plain Old JavaScript Objects which represent the effect intent, which you yield and then the redux-saga middleware itself performs the effect internally, hidden from you, providing the results back to your yield, like yourSaga.next(response).
Some like this because your saga generators are truly pure. Because it uses generators to support multiple effects, it makes it easy to test without mocks because you just assert that the effects it yielded are expected. Personally, I found in practice this seemed far cooler than it really is: many times you end up effectively recreating everything the saga does in your test. You are now testing the implementation of the saga is correct not testing the behavior of the saga. Many don't care (or even notice this), but I did. I imagine some even prefer it. This is called "effects as data". FWIW, redux-observable does not use this "effects as data" model, which is the most fundamental difference between it and redux-saga.
Tying this back to how they compare to redux-thunk, the biggest differences are: time-based operations (e.g. debouncing sequential actions) are impractical with redux-thunk alone without major hacks. Speaking of debouncing, it doesn't come with any utilities at all, so you're on the your handling debouncing and other common effects. Testing is much much harder.
These are mostly opinions, however. Certainly very successful applications can (and have) use redux-thunk. https://m.twitter.com comes to mind.
I think it wouldn't be controversial to say that redux-thunk is significantly easier to learn and use for simple request->response AJAX calls, without needing cancellation, etc. In fact, I often recommend users unfamiliar with RxJS use redux-thunk for the simple stuff and only lean on redux-observable for the more complex stuff, so they can remain productive and learn as they go. There's definitely a place for academic "correctness" and beautiful code, but for most people's jobs, shipitâ„¢ should be #1 priority. Users don't care how correct our code is, only that it exists and [mostly] works.
Regarding opinions on redux-saga vs. redux-observable, I'm biased because I'm one of the authors of redux-observable, but I summarized some of my thoughts in a previous SO post: Why use Redux-Observable over Redux-Saga? tl;dr they have a similar overall pattern, but redux-saga uses "effects as data" whereas redux-observable uses real effects with RxJS. Pros and cons to both, the primary pro to using RxJS that it is a skill that is a vastly useful skill for things other than redux-observable, and will almost certainly outlive redux-observable/redux-saga so the skill is highly transferable.
I know, that in most cases services preferable, because they are initiated directly at the call site and this approach making code more clear.
While harder to reason, what a system doing, when things are spread out over events.
When using listeners is better than using services?
How to use listeners and keep code clear?
Please, give some examples. Any help would be appreciated! Thanks a lot!
Listeners make sense when you create a reusable bundle/component that should not be modified by its clients but still be extensible.
Listeners don't make much sense for application code because they add a level of indirection that makes it harder to figure out what's going on.
Can synchronous and asynchronous functions be integrated into one call/interface whilst maintaining static typing? If possible, can it remain neutral with inheritance, i.e. not wrapping sync methods in async or vice versa (though this might be the best way).
I've been reading around and see it's generally recommending to keep these separate (http://www.tagwith.com/question_61011_pattern-for-writing-synchronous-and-asynchronous-methods-in-libraries-and-keepin and Maintain both synchronous and asynchronous implementations). However, the reason I want to do this is I'm creating a behaviour tree framework for Dart language and am finding it hard to mix both sync and async 'nodes' together to iterate through. It seems these might need to be kept separate, meaning nodes that would suit a sync approach would have to be async, or the opposite, if they are to be within the same 'tree'.
I'm looking for a solution particularly for Dart lang, although I know this is firmly in the territory of general programming concepts. I'm open to this not being able to be achieved, but worth a shot.
Thank you for reading.
You can of course use sync and async functions together. What you can't do is go back to sync execution after a call of an async function.
Maintaining both sync and async methods is in my opinion mostly a waste of time. Sometimes sync versions are convenient to not to have to invoke an async call for some simple operation but in general Dart async is an integral part of Dart. If you want to use Dart you have to get used to it.
With the new async/await feature you can write code that uses async functions almost the same as when only sync functions are used.
I am using Weld to observe events. I thought there was a way to specify if the observer was asynchronous or not, but I am not finding that annotation or documentation.
Can observers be asynchronous, if so, what do I need to do to make that happen?
There is an open request for this: CDI-31: Asynchronous events.
Depending on your requirements, you can, as indicated in your comment, set a different transactional observer: If you use AFTER_COMPLETION or AFTER_SUCCESS, it should seem to your application like an asynchronous execution. However until a framework solves , I have just found an example using JMS for asynchronous execution in CDI.
Take a look at post on Piotr Nowicki's blog http://piotrnowicki.com/2013/05/asynchronous-cdi-events/
He described a couple of methods for achieving asynchronous behavior of CDI events.
If you guys want to see this happen, you'll need to head over the the link provided in Kariem's answer and voice your opinion. It seems the expert group is unwilling to consider adding async events because they consider it bloating the spec.
Honestly, Guice manages to offer this feature, and it remains lightweight, so I find the argument against this little counter-intuitive. Nevertheless, if you want to see this feature, head to the link, voice your opinion.
-Jonathan
I was recently watching a webcast on Clojure. In it the presenter made a comment in the context of discussing the FP nature of Clojure which went something like (I hope I don't misrepresent him) "Mock objects are mocking you".
I also heard a similar comment a while back when I watched a webcast when Microsoft's Reactive Framework was starting to appear . It went something like "Mock objects are for those who don't know math")
Now I know that both comments are jokes/tongue-in-cheek etc etc (and probably badly paraphrased), but underlying them is obviously something conceptual which I don't understand as I haven't really made the shift to the FP paradigm.
So, I would be grateful if someone could explain whether FP does in fact render mocking redundant and if so how.
In pure FP you have referentially transparent functions that compute the same output every time you call them with the same input. All the state you need must therefore be explicitly passed in as parameters and out as function results, there are no stateful objects that are in some way "hidden behind" the function you call. This, however, is, what your mock objects usually do: simulate some external, hidden state or behavior that your subject under test relies on.
In other words:
OO: Your objects combine related state and behavior.
Pure FP: State is something you pass between functions that by themselves are stateless and only rely on other stateless functions.
I think the important thing to think about is the idea of using tests help you to structure your code. Mocks are really about deferring decisions you don't want to take now (and a widely misunderstood technique). Instead of object state, consider partial functions. You can write a function that takes defers part of its behaviour to a partial function that's passed in. In a unit test, that could be a fake implementation that lets you just focus on the code in hand. Later, you compose your new code with a real implementation to build the system.
Actually, when we were developing the idea of Mocks, I always thought of Mocks this way. The object part was incidental.