RxJS Observables vs Promises

Ben Lesh
InstructorBen Lesh
Share this video with your friends

Social Share Links

Send Tweet

Let's look at some of the basic features of RxJS Observables as asynchronous primitives, by comparing them to their cousins, Promises.

[00:02] Getting to started I've already included my RxJS script. I have a console clear to keep my console from being junked every time I run. I've switched JS Bin to 6 to 5 or Babel so I have access to arrow functions and other ES6 features.

[00:15] For a long time in JavaScript, handling asynchronous values has come down to callbacks or Promises. Being an asynchronous primitive, Promises are often compared to RxJS Observables. To illustrate the difference between Promises and Observables, I am going to create a Promise from scratch.

[00:54] I'm going to call then on it, and we'll just log out the value we get back. There's a slight delay, and then we see 42. To show the delay, find a log to show when the promise is starting. Again, promise started, 42.

[01:14] To show this exact same thing in an Observable, I'm pretty much going to copy and paste the same code. Only this time I'm going to create a RxJS Observable. I'm not going to have a resolve function. Instead I'm going to have an observer that I call next on. Of course, my Observable is started.

[02:00] I use for each instead of then. When I run this you see they both start, and they both emit their values. They're very similar at this point. One really important difference can be shown if I comment out my then and my for each.

[02:20] This difference is that Observables are lazy and Promises are not. What I mean by lazy is when I run this you can see the promise started. It actually hit this block of code and ran the entire thing, which means my timeout actually did resolve. I'll run it again. It hit the success handler or the handler for my timeout where this block here wasn't executed at all.

[02:55] Why is that interesting? That is interesting because if I have a promise it's always going to fire the block that's inside of here. If it's setting up some asynchronous call, the instant you have a promise it's going to fire that asynchronous call, be it Ajax, setting up some event handler, or what have you. That is already done by the time you have access to the promise.

[03:19] If I have this Observable, this source, the Observable actually embodies everything that's necessary to set up its own data source. What kind of advantage do we have with Observables having this lazy feature? Another thing that Observables do is they actually embody not only the setup, this bit here, for their own data source, but the teardown.

[03:44] If I was to add this exact some logging message to my timeout in my Observable -- we'll make it unique -- and I were to track the ida from my set timeout and return a function here that clears that time out, this actually will be called to teardown my Observable if I cancel it. Let's make these delays just a little bit longer, one second.

[04:25] Now when I subscribe to these things I'm going to get my disposable that is returned from my for each subscription. I'll set a slightly quicker timeout and call dispose on it. What this is going to do is about a half second as opposed to a second here. I'm going to call dispose, and that's going to call what's inside of this function.

[05:00] We know it's been called. I can run this, and you'll see it's started my Observable but then it called dispose. My promise timeout was hit, which is this guy up here, but not my Observable. To better illustrate this, let me comment out this promise and run this again.

[05:28] You'll see it started my Observable, which means it hit this, called all this here. But then dispose was called here first. It called "My disposal method" which cleared my timeout, which means that this timeout never got called and never emitted a value.

[05:48] Observables can actually embody the setup and teardown for their data sources. What does that mean? That means, unlike Promises, Observables can be canceled because they embody everything that's necessary to tear themselves down.

[06:04] Likewise -- because Observables embody everything that's necessary to set themselves up -- Observables can be called again as long as you have access to them. If I were just to have this variable here, this Promise, and I called then again, it's not going to run this code again. It's just going to return the same value it already had.

[06:26] That means if I have an Observable that's errored, I can simply subscribe to it again to retry it or use one of the retry operators such as "Retry or retryWhen." Whereas with a Promise if the Promise has errored, I better have access to whatever function returned the Promise because the Promise has already executed its own logic.

[06:45] More importantly, the logic to create the Promise is already executed. It is a read only view to a future and cannot be repeated or retried.