What the hell is reactive programming?
Hello fellow steemians,
as a developer since the early 2000s one of the most interesting topics for me to learn was the concept of reactive programming. I started as a Java developer working with relational databases. I am talking SQL, a lot of it actually. When I was in school I had the most fun designing beautiful and efficient entity relation diagrams. I love modelling data, I also haven't got a tan in 4 summers.
After 6 years working with the same concepts over and over again (mostly Java with a variety of database-flavors mixed into my enterprise world) work got stale. The challenge so to say was in overcoming my lack of motivation, rather than getting exited overcoming a given problem.
When I discovered NodeJS the whole perception of my career changed. I was and still am excited being able to learn a lot of new and interesting stuff on a daily basis. I could fill a book with just scratching on the surface of the NodeJS universe but for now I want to focus on rxJS which got introduced to me as part of the Angular framework.
It's been a long way
rxJS is a fairly new library for reactive programming in the JavaScript language. It takes a different approach on asynchronous tasks which was done using callback-methods or promises historically. An asynchronous task is a task where you don’t really know when this task is performed, completed or how long it is going to take. A callback is simply a function that gets executed whenever another function completes.
function simpleHTTPCall(var1, callback){
someHTTPRequest(var1).then((data) => {
// do something with the data
callback();
});
}
simpleHTTPCall('test', function() {
console.log('Data received, finished.');
});
In this example when simpleHTTPCall gets executed we see the message in the developer console after the data is received. This way it is possible to know exactly whenever we reach the end of our function. Whenever we have to wait we need to make sure not to block ourselves. If we actively wait until something happens our app will freeze. In the example above any code after the call will still get executed until the callback( ) triggers the console.log( ). This is what we call a hook. It was the most common approach on asychronous tasks when I started coding JavaScript a while back. Now I want to show you what rxJS is all about.
Observables, Observers and Subscriptions. A love triangle
The observable pattern itself is implemented with 3 components in mind. The observer, some sort of datasource to be observed and in between a stream (a timeline). On this timeline we can have multiple events emitted by the observable or data packages. It depends on the data source of that observable of course.
The observable
You can think of an observable as a data source. It could emit data because you trigger it to do so. You can do that programmatically or it could be connected to a button and therefore whenever the button is clicked an event gets emitted in a data package. In the case of a http request data gets emitted whenever a response is received.
The observer
You are the observer! It is your code, your subscribe function. You have 3 possible events you can hook into.
- You're going to handle data
- You're going to handle an error
- You're going to handle success
Let me give you an example. By defining my own Observable with some simple setTimeOut( ) functions in TypeScript using the rxjs library.
const myObservable = Observable.create((observer: Observer<String>) => {
setTimeout(() => {
observer.next('first message');
}, 2000);
setTimeout(() => {
observer.next('second message');
}, 3000);
setTimeout(() => {
observer.complete();
}, 4000);
setTimeout(() => {
observer.next('third message');
}, 6000);
});
This is our custom observable. Its job is to emit a string value after 2 and 3 seconds. After the 4th second it completes. The third message will not get emitted because it should be emitted at 6 seconds. To hook into what's happening we use a subscription.
The subscription
Let us start with extending the example from above by adding a subscription.
mySubscription: Subscription;
mySubscription = myObservable.subscribe((data: string) => {
// handle data
console.log(data);
}, (error: string) => {
// handle error
console.log(error);
}, () => {
// handle completion
console.log('completed');
});
By calling the subscribe method of our observable we get a subscription in return. It takes 3 functions as arguments, the first one being the function to handle the data, the second one to handle an error and the third one handles completion. In our case we would console.log( ) the emmited 'first message', after that the 'second message' and finally 'completed'.
If you subscribe to something like the 'click'-event on a button you won't get a complete message because they can happen any time. In all cases you should unsubscribe to a subscription whenever you are not using it. Memory leaks are a real issue when working with them. In Angular you should call the unsubscribe method of your components subscriptions whenever the component gets destroyed (you click a link and route inside your app).
Wrap up
So basically observers, obervables and subscriptions are just another approach to a common problem. What sets it really apart for me are the operators. Which I will introduce you to in my next blog post.
Thanks for reading. Hope you enjoyed it.
Interesting contribution. I remember my first approaches with reactive programming. For someone who comes from imperative programming and OOP it's quite unusual, but nevertheless it definitely offers a lot of posibilities.
Congratulations @dorfid! You received a personal award!
Click here to view your Board
Congratulations @dorfid! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!