Saturday 7 May 2016

Iterators and Observers in asynchronous javascript - part 2

Iterators and Observers in asynchronous javascript


You can think of Observable as a DOM event where you pass three handlers instead of one handler.


  1.  Step 1: The first handler is for getting the next data. It is equivalent to calling the next() method on an iterator to consume the next data. But in the iterator pattern it is the consumer that is the in-charge of the game. The consumer decides when to consume more data by calling the next() method. But in the Observable here it is the producer of the data that is in-charge and decides when to push new data to the consumers.
  2. Step 2: The second handler is optional and handles a siutation when an error occurs. The Observable pushes information to consumers that an error has occurred so that consumers know what is going on. It is equivalent to the phenomena of throwing error in the iterator pattern where the producer throws error when the consumer calls next() mehtod AND there is an error. But the consumer's action of calling the next() method causes the throwing of the error by the prouducer, so the consumer is incharge in the iterator pattern. Here in the Observable it is the producer who is inchage and decides to inform the consumers that an error has occured without any action on the part of consumers.
  3. Step 3: The thrid step is that the producer informs the consumer that it has no more data for the consumers. The producer is the in-charge and pushes out the information to the consumers that it has no more data for them. It is equivalent to the operation in the iterator pattern when the method next() is called and the producer sends the done: true to indicate that it has no more data. But in the iterator method it is the consumer whose calling of next() on the iterator causes this sending of done: true to indicate that the end of data. In the Observable it is the producer who pushes the information without any action on the part of consumers. This is an optional handler in the Observable.

 
    //Here is an Observable
    //The function fromEvent has been used rom the RxJs library to make the Observable.
    //element could be a button, a link, the document itself or any other element in the DOM.

var mouseMoves = Observable.fromEvent(element, "mouseMove");

 Using the forEach on the Observable the same way we do it on an array but array is blocking and we don't want blocking. In an Observable data arrives over time and with the arrival of the data the forEach works on the freshly arrived data.

//subscribe
    var subscription = mouseMoves.forEach({
        //step 1. next data
        event => console.log(event), /* event is the argument that the function gets whereas the function's body is on the right hands side of =>.*/
        //step 2. error occurs - optional step
        error => console.error(error), /* error is the argument that the function gets whereas the function's body is on the right hand side of =>.*/
        //step 3. data transfer completed - no more data - optional step
        () => console.log("done. No more data.") /* No argument to the function is represented by () and the body of the function handles what to do.*/
    }
    );
     
 If you want to consume the data inside an Observable then you have to make an object Observer with three handlers. Then hand the Observer object to the Observable and the Observable will push data into the Observer object and by extension your call backs in the Observer object.

 In the code below we are passing an object to the Observable mouseMoves. In th object we have name: value pairs for all the three steps discussed earlier. In the code above we just passed three functions to the Observable mouseMoves and not an object.

var subscription = mouseMoves.forEach({
   
      onNext: event => console.log(event),
      onError: error => console.loge(error),
      onCompleted: () => console.log("done")
   
  });
  //unsubscribe
  subscription.dispose();

/*******************************************************************************/
//Here is the method fromEvent

/* Converting Events to Observables. */
//fromEvent is a static method in the Observable.
Observable.fromEvent = function(dom, eventName){
    //returning Observable object
    return{
        forEach: function(observer){
            /* observer is an object with three things 1. onNext to push more data 2. onError to push error message 3. onCompleted to push "done" to consumers.*/
            var handler = (e) => observer.onNext(e);
            dom.addEventListener(eventName, handler);
            //returning Subscription object
            return{
                dispose: function(){
                    dom.removeEventListener(eventName, handler);
                }
            };
        }
    };
}

No comments:

Post a Comment