Comparing the Pull mechanism with the RxJava Push mechanism

RxKotlin revolves around the Observable type that represents a system of real-life events and data, intended for push mechanisms, thus it is lazy and can be used in both ways—synchronously and asynchronously.

It'll be easier for us to understand if we start with a simple example that works with a list of data:

fun main(args: Array<String>) { 
    var list:List<Any> = listOf(1, "Two", 3, "Four", "Five", 5.5f) // 1 
    var iterator = list.iterator() // 2 
    while (iterator.hasNext()) { // 3 
        println(iterator.next()) // Prints each element 4 
    } 
} 

The output is as follows:

Let's go through the program line by line to understand how it works.

At comment 1, we created a list with seven items (the list contains data of mixed data types with the help of Any class). At comment 2, we created iterator from the list, so that we can iterate over the data. In comment 3, we created a while loop to pull data from the list with the help of an iterator, and then at comment 4, we printed it.

The thing to notice here is that we're pulling data from the list while the current thread is blocked till the data is received and ready. For instance, think of getting that data from a network call/database query instead of just a list, and in that case, how long the thread will be blocked. You can obviously create a separate thread for those operations, but that too will increase complexity.

Just give it a thought, which one is a better approach, making the program wait for data or pushing data to the program whenever it's available?

The building blocks of the ReactiveX framework (be it RxKotlin or RxJava) are the observables. The Observable class is opposite to Iterator. It has an underlying collection or computation that produces values that can be consumed by a consumer. But the difference is that the consumer doesn't pull these values from the producer like in the Iterator pattern; instead the producer pushes the values as notifications to the consumer.

So, let's take the same example again, this time with observable:

fun main(args: Array<String>) { 
    var list = listOf(1, "Two", 3, "Four", "Five", 5.5f) // 1 
    var observable = list.toObservable(); 
 
    observable.subscribeBy(  // named arguments for lambda Subscribers 
            onNext = { println(it) }, 
            onError =  { it.printStackTrace() }, 
            onComplete = { println("Done!") } 
    ) 
} 

This program's output is the same as the previous one; it prints all the items in the list. The difference is in its approach. So, let's see how it actually works:

  1. Created a list (the same as the previous one)
  2. An Observable instance is created by the list
  3. We subscribe to the observer (we're using named arguments for lambda; we will cover them in detail later)

As we subscribe to the observable variable, each data will be pushed to onNext as it gets ready; it'll call onComplete when all the data is pushed, and onError if any error occurs.

So, you learned how to use the Observable instances and that they are quite similar to the Iterator instances, something we're quite familiar with. We can use these Observable instances for building asynchronous streams and pushing data updates to their subscribers (even to multiple subscribers). This was a simple implementation of the reactive programming paradigm. The data is being propagated to all the interested parties—the subscribers.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.219.71.21