All:
I am very new to Rx.js( I heard this name from a tech meeting ), what im curious about is how to use it in real project(or say what is its usercase), and could anyone give me an example in which situation that a job Rx.js can do but Promise can not do(or just much easier to do in Rx.js)?
Thanks
Your question is too vague and open-ended. I recommend doing some reading, but if you want the short version:
Observables...
Return a logical "infinite" number of values and a "completion" when this "infinite sequence" concludes, or throw an error
Have a Creation/Subscription/Disposal lifecycle
Can actually model a series of HTTP requests and their cancellation
Are based on functional programming techniques and are reactive
Are very good for modeling async data flows
Are lazily evaluated based on subscribers
Promises...
Return a single value asynchronously or reject/throw an error
Are created and then by definition either resolve or reject
Can model a single HTTP request that will be fulfilled
Are not really FP based (there are multiple GH issues about this, they are almost all full of drama and aren't very much worth reading)
Can only model single tasks
Are eagerly evaluating by design
Some may mistake this as an attack on Promises, but Promises are usually good enough for single-value async. But Rx users probably don't like Promises because they feel like they only have a subset of features with less features compared to Observables.
Related
I've just learned about CQRS, and I would like to combine it in a project with a GraphQL based API. However, in order to do that, a question has come to my mind: according to CQRS, commands have to not return anything after its execution. However, according to GraphQL conventions, mutations have to return the updated state of the entity.
How should I deal with that? Are CQRS and GraphQL incompatible? The only solution that comes to my mind is, in order to resolve the mutation, first execute a command and later a query, in order to get the response object. Is there anything better than that? It doesn't look very efficent to me...
Thanks in advance
How should I deal with that?
Real answer? Ignore the "have to not return anything" constraint; the underlying assumptions behind that constraint don't hold, so you shouldn't be leaning to hard on it.
How exactly to do that is going to depend on your design.
For example, if you are updating the domain model in the same process that handles the HTTP Request, then it is a perfectly reasonable thing to (a) save the domain model, (b) run your view projection on the copy of the model that you just saved, (c) and then return the view.
In other words, the information goes through exactly the same transformations it would "normally", except that we perform those transformations synchronously, rather than asynchronously.
If the model is updated in a different process, then things get trickier, since more message passing is required, and you may need to deal with timeouts. For instance, you can imagine a solution where you send the command, and then poll the "read side" until that model is updated to reflect your changes.
It's all trade offs, and those trade-offs are an inevitable consequence of choosing a distributed architecture. We don't choose CQRS because it makes everything better, we choose CQRS because it makes some things better, other things worse, and we are in a context where the things it makes better are more important than the things it makes worse.
I am considering similar, i.e. using GraphQL predominantly for interfacing with the read-side of a system based on CQRS.
On the write-side, however, I am considering using a Web or REST API that has one end-point that accepts commands.
Remember, in CQRS you don't directly mutate entities but submit a command signalling your intent / desire to do something.
Alternatively, thinking out loud here, it may be possible to use mutations in GraphQL to create commands and track their status using subscriptions.
I usually see the use of either promise and future in the start of a vert.x verticle. Is there any specific difference between both?
I have read about their differences in Scala language, is it the same in case of Vert.x too?
Also when should I know when to use promise or a future?
The best I've read about:
think on Promise as producer (used by producer on one side of async operation) and Future as consumer (used by consumer on the other side).
Futures vs. Promises
Promise are for defining non-blocking operations, and it's future() method returns the Future associated with a promise, to get notified of the promise completion and retrieve its value. The Future interface is the result of an action that may, or may not, have occurred yet.
A bit late to the game, and the other answers say as much in different words, however this might help. Lets say you were wrapping some older API (e.g. callback based) to use Futures, then you might do something like this :
Future<String> getStringFromLegacyCallbackAPI() {
Promise<String> promise = Promise.promise();
legacyApi.getString(promise::complete);
return promise.future();
}
Note that the person who calls this method gets a Future so they can only specify what should happen in the event of successful completion or failure (they cannot trigger completion or failure). So, I think you should not pass the promise up the stack - rather the Future should be handed back and the Promise should be kept under the control of the code which can resolve or reject it.
A Promise as well is a writable side of an action that may or not have occurred yet.
And according to the wiki :
Given the new Promise / Future APIs the start(Future<Void>) and stop(Future<Void>) methods have been deprecated and will be removed in Vert.x 4.
Please migrate to the start(Promise) and stop(Promise) variants.
As a paraphrase,
A future is a read-only container for a result that does not yet exist, while a promise can be written (normally only once).
More from here
I noticed that when I unsubscribe from query, http request is still executing and not being canceled. Also tried to use AbortController but without any luck. How does one cancel http requests made by Apollo client?
This is an old question, but since I just wanted to do the same and managed to do it with the latest Apollo Client (3.4.13) and Apollo-Angular (2.6.0), you need to make sure that you're using watchQuery() instead of query(), and then call unsubscribe() on the returned Apollo subscription from the previous request. The latter implies of course that you should store somewhere the subscription object that you want to abort.
This is an old question, but I spent two days on this bananas problem and I want to share for posterity.
We're using Angular and GraphQL (apollo-angular and codegen to make GraphQL services) and we opted for an event-driven architecture using NgRx to send events and then perform http calls. When sending multiple identical events (but with different property values) we noticed we got stale data in some cases, especially edge cases like when 20+ of these identical events were sent. Obviously not common, but not ideal, and a hint of perhaps bad scale since we were going to need many more events in future.
The way we resolved this issue was by using .watch() instead of .fetch() on the GraphQL generated services. Initially, since .fetch() returned the same Observable as .watch().valueChanges, we thought it was easier and simpler to just use .fetch(), but their behavior seems much different. We were never able to cancel http requests performed by .fetch(). But after changing to .watch().valueChanges, the Observable acted exactly as http request Observables would, complete with -- thankfully -- cancelation.
So in NgRx, we swapped our generic mergeMap operator for the switchMap operator. This will ensure previous effects listening on dispatched events will be canceled. We needed no extra overhead, no .next-ing to Subjects, no extra Subscriptions. Just change .fetch() into .watch().valueChanges and then switchMap to your heart's content. The takeUntil operator will now also cancel these requests, which is our performed method of unsubscribing from Observables.
Sidenote: I'm amazed that this information was this hard to come by, and honestly this question and one GitHub issue was all I could find to intimate this discrepancy. Even now I don't quite understand why anyone would want .fetch() if all it does is perform an http call that will always resolve and then return an Observable that does not behave the way you expect Observables to behave.
What's the difference between RxJS and IxJS, and when would I want to use one over the other?
From the IxJS docs:
RxJS is great for event-based workflows where the data can be pushed at the rate of the producer, however, IxJS is great at I/O operations where you as the consumer can pull the data when you are ready.
After going through the docs, the only major difference seems to be the concept of Iterables in IxJS and Observables in RxJS.
Both Iterables and Observables execute either synchronously or asynchronously, and the .forEach from IxJS is essentially the same as RxJS's .subscribe method when paired with the almost-identical from creator function. The only other difference is IxJS's .forEach method is optional because you could use the imperative for-of instead.
It seems like there are two libraries for no reason because RxJS's from creator function can convert Iterables to Observables.
From my perspective, it's not really IxJS and RxJS, it's Iterables and Observables. How are they different and when would you use one over the other?
tl;dr
RxJS processes values as soon as they arrive. It's a push system.
IxJS specifies when to pass in the next value. It's a pull system.
Explanation
IxJS may be helpful if want to have pull-based model, for example, when dealing with backpressure.
As you can see in the documentation:
IxJS unifies both synchronous and asynchronous pull-based collections, just as RxJS unified the world of push-based collections. RxJS is great for event-based workflows where the data can be pushed at the rate of the producer, however, IxJS is great at I/O operations where you as the consumer can pull the data when you are ready.
In other words:
Use RxJS if your producer (usually User) is slower that processing of data (this is common for frontend).
Use IxJS if your producer (usually System) is much faster than you can process data (more common for the backend).
To understand what this means, consider the following example:
You need to build ETL pipeline and process a large file (about 1TB).
If you write it with RxJS, something like:
readFileByLineObservable('path/to/file')
.pipe(
doSomeHeavyTransformation(),
)
.subscribe()
Then readFileByLineObservable will try to "push" the entire file of 1TB into RAM as soon as possible. Only after this occurs, you will start to do doSomeHeavyTransformation. This problem is called backpressure.
In contrast, IxJS will try to "pull" each newline only after previous line was processed. That's the optimal processing method in this case.
The difference is how RxJS's .subscribe sets up a listener whereas IxJS's .forEach tells its iterator when to give the next value (only after its done processing the first one. It's similar to, but not the same as, RxJS's concatMap and concatAll operators.
As a complement to Oles Savluk answer, I found Matt Podwysocki's explanation particularly useful (https://gist.github.com/mattpodwysocki/1d0fe43961c6222571386568b8a5ef23):
we have four types of collections, each with their own purpose. Each
has its own place, and there's no one solution that rules them all.
Pull: Iterable - purely synchronous data, either finite or infinite
Push: Observable / Subject/Observer - eventual data such as DOM events, collections over time
Pull/Push: AsyncIterable - I/O or other asynchronous data where the consumer needs to be in control
Push/Pull: AsyncObservable - Network calls where creation/teardown may be asynchronous as well as projections may be asynchronous too.
Matt is a contributor to both RxJS and IxJS.
Iterable and AsyncIterable come from IxJS, Observable and AsyncObservable are developed in RxJS
I am looking for a pub/sub mechanism that behaves like a promise but can resolve multiple times, and behaves like an event except if you subscribe after a notification has happened it triggers with the most recent value.
I am aware of notify, but deferred.notify is order-sensitive, so in that way it behaves just like an event. eg:
d.notify('notify before'); // Not observed :(
d.promise.progress(function(data){ console.log(data) });
d.notify('notify after'); // Observed
setTimeout(function(){ d.notify('notify much later') }, 100); // Also Observed
fiddle: http://jsfiddle.net/foLhag3b/
The notification system I'd like is a good fit for a UI component that should update to reflect the state of the data behind it. In these cases, you don't want to care about whether the data has arrived yet or not, and you want updates when they come in.
Maybe this is similar to Immediate mode UIs, but is distinct because it is message based.
The state of the art for message based UI updating, as far as I'm aware, is something which uses a promise or callback to initialize, then also binds an update event:
myUIComponent.gotData(model.data);
model.onUpdate(myUIComponent.gotData); // doing two things is 2x teh workz :(
I don't want to have to do both. I don't think anyone should have to, the use case is common enough to abstract.
model.whenever(myUIComponent.gotData); // yay one intention === one line of code
I could build a mechanism to do what I want, but I wanted to see if a pub/sub mechanism like this already exists. A lot of smart people have done a lot in CS and I figure this concept must exist, I just am looking for the name of it.
To be clear, I'm not looking to change an entire framework, say to Angular or React. I'm looking only for a pub/sub mechanism. Preferably an implementation of a known concept with a snazzy name like notifr or lemme-kno or touch-base.
You'll want to have a look at (functional) reactive programming. The concept you are looking for is known as a Behavior or Signal in FRP. It models the change of a value over time, and can be inspected at any time (continuously holds a value, in contrast to a stream that discretely fires events).
var ui = state.map(render); // whenever state updates, so does ui with render() result
Some popular libraries in JS are Bacon and Rx, which use their own terminology however: you'll find properties and observables.