This article describes the refCount operator and explains that in order to prevent the unsubscription of obervable A we have to add delay(0) to the source observable such that th import { Observable } from "rxjs/Observable";
const source = Observable.defer(() => Observable.of(
Math.floor(Math.random() * 100)
)).delay(0);
Is 0 always enough? In other words does passing zero guarantee that the notification will be delayed until all m.subscribe() statements have run, assuming they are all run immediately following the multicast statement like this:
const m = source.multicast(() => new Subject<number>()).refCount();
m.subscribe(observer("a"));
m.subscribe(observer("b"));
In the above case we are only subscribing observers a and b. If we subscribed a million observers after the multicast statement would running delay(0) still guarantee taht they all will be subscribed before the first source notification happens?
To understand the issue you must know that:
Javascript is single threaded;
Asynchronous events runs in event loop (a.k.a. Micro Task and Macro Task)
When Async event happens, it is added to the Event loop;
After async event added to the Event loop, Javascript continues with synchronous code;
After no synchronous code left, it runs events code from Event loop.
This Observable would be synchronous if you wouldn't add delay(0):
const source = Observable.defer(() => Observable.of(
Math.floor(Math.random() * 100)
)).delay(0);
When first Subscription happens (subscribing is synchronous code), Observable emits immediately, because it is also synchronous. But if you add delay(0) (similar to setTimeout), Javascript will wait until all synchronous code (all source.subscribe() in this case), are executed. After that it will run asynchronous delay(0)).
And here:
const m = source.multicast(() => new Subject<number>()).refCount();
m.subscribe(observer("a"));
m.subscribe(observer("b"));
You have source Observable which becomes asynchronous after its emition is passed to delay(0). At that point, synchronous code will continue (all your other source.subscribe() calls) and after they are done, synchronous delay(0) will emit.
So it is safe even for millions source.subscribe() calls to get executed in this case.
p.s.
multicast(() => new Subject<number>()).refCount() is exactly the same as share() - it takes multicast with Subject factory and counts active subscriptions with refCount.
Let's say I have the following code in empty AngularJS controller:
Promise.all([Promise.resolve()]).then(() => console.log('Then'));
setTimeout(() => console.log('setTimeout callback'));
I expect:
Promise.all.then will be put into the event loop.
setTimeout callback will be put into the event loop.
We don't make any long requests and there should be the following output:
Then
setTimeout callback
And it works.
But if we replace Promise.resolve() by $q.resolve():
Promise.all([$q.resolve()]).then(() => console.log('Then'));
setTimeout(() => console.log('setTimeout callback'));
the output will be different:
setTimeout callback
Then
Here is a plunk: https://embed.plnkr.co/0h0i4CzuSgqMbYQtxZtU/
Why is the output different? How does $q.resolve affect the output?
Some reasons:
Promise.all doesn't "detect" already-fulfilled promises, and returns an immediately resolved promise because of that. It always waits for its input promises, using their .then() method (also it needs to assimilate non-native promises through this anyway). Since then callbacks are always asynchronous, the Promise.all(…) result always is resolved asynchronously (unless the iterable is empty), and the Promise.all(…).then(…) callback is scheduled later
There is not a single event queue on the event loop, but multiple ones for different sources. So even if the promise things take more "ticks" of the event loop, their queue is simply served more often than, and before, the timeout queue.
We don't know what mechanism $q is using for making its promise callbacks asynchronous. We only know that it's not the native promise one, and therefore using a different, apparently "slower", queue.
In general, you cannot (should not) rely on asynchronous callbacks to be called in any specific order, except their documentation mentions it. Make the ordering explicit (e.g. using promises) when you need it.
How do I know when an Observable producer is async or sync?
An sync example:
Observable.of([1, 2, 3])
another async example (ngrx Store, see here)
this.store.take(1);
And now an obvious async example:
this.http.get(restUrl)
I fully understand how this works, and that some Observables can be sync and others Async. What I don't understand is how i can tell the difference in advance? Is there for example an obvious interface on the producer that tells me that it will be async?
tl;dr
The main reason this question has come up is because of the answer from the link above (here).
#Sasxa has (correctly) answered that we can use a synchronous call to get the latest value from the ngrx store:
function getState(store: Store<State>): State {
let state: State;
store.take(1).subscribe(s => state = s);
return state;
}
However knowing that observables are usually asynchronous, I saw this and immediately thought RACE CONDITION! the method could return an undefined value before subscribe has called back the function.
I've debugged through the internals of Store and Observable and this example is indeed synchronous, but how should I have known that? For those that know ngrx, the select method of store (used to get the latest values) is asynchronous, without a doubt, as this is what gives us the reactive gui, which is why I came to the assumption I did.
It means that I cannot refactor the code above as follows:
function getLatest(observable: Observable): any {
let obj: any;
observable.take(1).subscribe(latest => obj = latest);
return obj;
}
I could call this with any Observable and it would work for synchronous producers - it may even work SOME OF THE TIME for async producers, but this is without a doubt a race condition if an async observable is passed in.
It is possible to determine if an observable is asynchronous for sure if was directly scheduled with asynchronous scheduler (Scheduler.async or Scheduler.asap), it's exposed as foo$.scheduler:
let schedulers = [null, Scheduler.asap];
let randomScheduler = schedulers[~~(Math.random()*2)]
let foo$ = Observable.of('foo', randomScheduler);
This information becomes even less available when foo$ is processed further, e.g. chained with other operators.
And it's impossible to determine if values will be produced synchronously (on same tick) or asynchronously because this depends on observable internals:
let foo$ = new Observable(observer => {
if (~~(Math.random()*2))
setTimeout(() => observer.next('foo'));
else
observer.next('foo');
});
TL;DR: it's impossible to know this for sure.
It is hard to figure out whether an observable you get is sync or async (imagine you get observables return from a thrid party library). That's why you write it in a fashion that the execution order is controlled and predictable.
That's also why there are operators like concat, combineLatest, forkjoin, switchMap, race, merge to help you get the order and performance right for different scenario
I'm still figuring out reactive programming so I'm pretty sure this is very basic, but the number of stream transformations is pretty overwhelming to a beginner.
I'm creating an Observable from a DOM event. This event should in turn trigger a REST call and all other DOM events will be ignored until this event has been resolved.
const stream = Observable.fromEvent(document, 'some-event')
stream
.flatMap(() => httpRestService())
.subscribe(() => {
})
How do I ignore the events from the stream until the last HTTP promise has resolved?
DOM event
A - - - - B - - - - C
HTTP event
D ...........done - C
You could try flatMapFirst which seems to do what you want. The following code could work (jsfiddle here - click anywhere) :
const stream = Observable.fromEvent(document, 'some-event')
stream
.flatMapFirst(() => httpRestService())
.subscribe(() => {
})
Quoting the documentation :
The flatMapFirst operator is similar to the flatMap and concatMap methods described above, however, rather than emitting all of the items emitted by all of the Observables that the operator generates by transforming items from the source Observable, flatMapFirst instead propagates the first Observable exclusively until it completes before it begins subscribes to the next Observable. Observables that come before the current Observable completes will be dropped and will not propagate.
UPDATE
Looking at the source code (https://github.com/Reactive-Extensions/RxJS/blob/master/src/core/linq/observable/switchfirst.js) it seems that while the the current observable has not completed, all the incoming observables in the meantime will be discarded, i.e. not subscribed to.
So if subscribing to these observables triggers the http call (would be interesting to see the code for httpRestService), then there is no unnecessary http call. If those calls are triggered immediately by calling the function and the result is passed through an observable, then there is a possibility that those calls are indeed triggered unnecessarily. In which case, that issue is easily solvable with using the defer operator to do the http call only at subscription time. In short, you need lazy execution of the rest request if you don't already have it.
So i've read that observables are looking to overtake promises in terms of usage in some of upcoming JavaScript MVC's:
Angular 2.0
Falcor used by Netflix
What is the difference between observables and promises?
Updated: Apologies! removed my falsy statement.
What is the difference between observables and promises?
Simply put: A promise resolves to a single value asynchronously, an observable resolves to (or emits) multiple values asynchronously (over time).
Concrete examples:
Promise: Response from an Ajax call
Observable: Click events
More information can be found here: http://reactivex.io/intro.html
i've read that observables are looking to overtake promises
Unlikely. Observables might be the better solution to certain problems, but that doesn't make promises obsolete (if that's what you mean).
Promises are a representation of 1 future value.
Observables are a representation for a possibly infinite amount of values.
Promises will trigger the fetching of that value immediately upon creation.
Observables will only start producing values when you subscribe to them. (Unless it's a hot observable, but that's outside the scope of this question)
Promises are designed to represent AJAX calls.
Observables are designed to represent anything: events, data from databases, data from ajax calls, (possibly infinite) sequences, etc.
Promises offer a very simplistic call back mechanism, where as Rx offers a powerful abstraction over asynchronous programming. An Observable represents a stream of data, which we can then apply operators to in order to define how the incoming data should be treated.
If all you need to do is make an HTTP request and then update a UI component, then using a Promise might suffice.
However, most apps tend to have more complicated needs than that (even if it’s not obvious at the first). Taking our HTTP request for example, let’s see how modelling this as an Observable and using some of the Rx operators can help us:
-If the HTTP request is triggered by a user action, we might want to be wary of firing off multiple HTTP requests (imagine a user typing into a search box). We don’t want to fire a request for every keystroke, so we might want to Throttle our search, so that we only fire a request if the user stops typing for 300ms. Furthermore, if user types a word, waits 300ms, and adds another character, we’ll fire off a subsequent HTTP request. With Promises, we’d probably encounter a race condition as we can’t control the order in which we’ll receive the responses and we can’t cancel old requests. Rx solves this by allowing us to Switch between streams, which calls Dispose on the old request subscriptions we no longer care about. We might also filter out any invalid search inputs, for instance Where the search term is less than 3 characters in length.
-Support for dealing with Timeouts/Error handling. Let’s say our HTTP request fails, Rx allows us to easily Retry making the request.
-Let’s say several parts of our application need to make the same HTTP call, we probably don’t want to actually make the call more than once. We can expose our observable to multiple consumers and use Replay to ensure the call is made once and the result is cached for subsequent subscribers. We can even supply a TimeSpan to Replay, giving us expiring cache behaviour.
-Powerful abstraction over threading through the use of Schedulers, which allows us to control concurrency. Even better, we can use Test Schedulers in our Unit Tests to control time, allowing us to simulate Timeouts, race conditions etc.
These are some quick examples to demonstrate what is possible. There are many more operators within the Rx framework to cater for all types of scenarios and the composability of Rx means you can easily combine operators to define the behaviour you need. It’s also easy to create your own reusable operators (e.g. RetryAfterDelay).
In summary, Rx can do everything than Promises can do, and far far more. I suspect in the next couple of years there'll be a continued shift towards Rx instead of Promises.
For further reading, I'd recommend taking a look at the section on Observables in the Angular 2 guide.
as said in Angular 2 guid
Converting to a Promise is often a good choice when you want to fetch a single chunk of data. so When you receive the data, you're done.
But in some cases requests aren't always done only once. You may start one request, cancel it, and make a different request before the server has
responded to the first request.
for example in a search component As the user types a name into a search box, you'll make repeated HTTP requests by that search query.
A request-cancel-new-request sequence is difficult to implement with
Promises, but easy with Observables.
so if your component gets data with only one request it's a good choice to use Promise but if it has a chain of request-cancel-new request you should use observable
Observables are often compared to promises. Here are some key differences:
Observables are declarative; computation does not start until subscription. Promises execute immediately on creation. This makes observables useful for defining recipes that can be run whenever you need the result.
Observables provide many values. Promises provide one. This makes observables useful for getting multiple values over time.
Observables differentiate between chaining and subscription. Promises only have .then() clauses. This makes observables useful for creating complex transformation recipes to be used by other part of the system, without causing the work to be executed.
Observables subscribe() is responsible for handling errors. Promises push errors to the child promises. This makes observables useful for centralized and predictable error handling.
Best explanation by angular on official website :
https://angular.io/guide/comparing-observables
Observables VS. Promises (by Jeremy Vilken)
In addition to new syntax, observables are a newer pattern for JavaScript applications to
manage asynchronous activities. They’re also a draft for a feature to be natively implemented in the JavaScript language so it has weight behind the pattern. RxJS is the
library we’ll use to help us implement observables in our applications.
Promises are another construct to help deal with asynchronous calls, which are useful
for making API requests, for example. Promises have a major limitation in that they’re
only useful for one call cycle. For example, if you wanted to have a promise return a
value on an event like a user click, that promise would resolve on the first click. But you might be interested in handling every user click action. Normally, you’d use an event
listener for this, and that allows you to handle events over time. This is an important distinction: Observables are like event handlers in that they continue to process data over
time and allow you to continuously handle that stream of data.
When you understand Observables correctly, the differences to Promises are pretty obvious.
The best way to demystify a convoluted concept is to implement it from scratch. Here is an almost purely functional Observable implementation and an example, that wouldn't work with Promises:
/*** Observable type ***/
// type constructor (of a product type)
const proType = name => cons => {
const f = (k, ...args) =>
Object.defineProperties({["run" + name]: k}, {
[Symbol.toStringTag]: {value: name},
[Symbol("args")]: {value: args}
});
return cons(f);
};
// value constructor
const Observable = proType("Observable")
(Observable => k => Observable(k));
/*** Observer factory ***/
const Observer = observer => {
let isUnsubscribed = false;
return {
next: function(x) {
if (isUnsubscribed)
throw new Error("unsubscribed");
else {
try {
return observer.next(x);
}
catch(e) {
isUnsubscribed = true;
this.cancel();
throw e;
}
}
},
error: function(e) {
if (isUnsubscribed)
throw new Error("unsubscribed");
else {
try {
return observer.error(e);
}
catch(e_) {
isUnsubscribed = true;
this.cancel();
throw e_;
}
}
},
complete: function() {
if (isUnsubscribed)
throw new Error("unsubscribed");
else {
try {
const r = observer.complete();
this.cancel();
return r;
}
catch(e) {
isUnsubscribed = true;
cancel();
throw e;
}
}
}
};
};
/*** combinators + auxiliary functions ***/
const subscribe = observable => handlers => {
const observer = Observer(handlers),
cancel = observable.runObservable(observer);
observer.cancel = cancel;
return cancel;
};
const obsMap = f => observable =>
Observable(observer => {
const mapObserver = {
next: x => observer.next(f(x)),
error: e => observer.error(e),
complete: () => observer.complete()
};
return observable.runObservable(mapObserver);
});
/*** main ***/
// create an Observable instance
const numStream = Observable(observer => {
let i = 0;
const timer = setInterval(() => {
observer.next(i++);
}, 1000);
return () => clearTimeout(timer);
});
// map a function over it
const squaredNumStream =
obsMap(x => x * x) (numStream);
// run the observable
const cancel = subscribe(squaredNumStream) ({
next: x => console.log(x),
error: e => console.error(e),
complete: () => console.log("finished")
});
// cancel it
setTimeout(cancel, 11000);
In the example above the Observable squaredNumStream emits a stream of theoretically infinite values asynchronously. You cannot do this with Promises, because they represent a single future value.
I could have easily subscribed to another squaredNumStream without both instances interfering with each other. This is because Observables are unicast, whereas Promises are multicast.
squaredNumStream doesn't run at declaration time, but only after subscription, because Observables are lazily evaluated. Promises on the other hand are eagerly evaluated that is, they start running as soon as you create them.
And finally, Observables are cancelable by design, whereas Promises are hard to cancel due to there unicast semantics.