Friday, December 30, 2016

JavaScript Evolution ESMAScript 6 - Promises

Typically, to avoid blocking the main thread of execution, we write non-blocking code using asynchronous style function pass callback like this:
getResult("Saas", function(result) {
  ui.renderSidebar(results);
}
When nested callbacks start to grow, our code becomes harder to read. We have to check for error on every callback.
getResultFromServer("Saas", function(error, results) {
  if (error) { // handle error };
  ui.renderSideBar(results, function(error, results) {
    if (error) { //handle error };
    sendNotificationToServer(results, function(error, response) {
      if (error) { // handle error };
      doSomethingElse (response, function(error)) {
        if (error) { //handle error };
        //...
      };
    };
  };
});
Promises brought to JavasScript trying to offer a solution to this issue by bringing new abstraction that allows us to write asynchronous code in an easier way.
getResultFromServer("Saas")
  .then(ui.renderSidebar)
  .then(sendNotificationToServer)
  .then(doSomethingElse)
  .catch(function(error) {
    console.log("Error :" + error);
  }
The Promise constructor function takes an anonymous function with 2 callback argument known as handles. Handles are responsible for resolving or rejecting the Promise.

Create a new Promise automatically set it to the pending state. Then, it can become fulfilled(resolve) or rejected(reject).

One thing to remember is that Promise not return a result, its return a future value, such as the eventual result if asynchronous operation.

Let's wrap the XMLHttpRequest object API within a Promise. Calling the resolve() handler moves the Promise to a fulfilled state. We'll call the reject() handler for unsuccessful status codes and also when the error event is triggered on our request object. Both move the Promise to a rejected state.
function getResultFromServer(pollName){
  return new Promise(function(resolve, reject) {
    request.onload = function() {
      if (request.status >= 200 && request.status < 400) {
        resolve(request.response);
      } else {
        reject(new Error(request,status));
      };
    };
    request.oneerror = function() {
      reject(new Error ("Error Fetching Results"));
    };
  };
};
We can use then() method to read results from the Promise once resolved. We can chain multiple calls to then(). The return value from 1 call is passed as an argument to the next.

Once an error occurs, execution moves immediately to the catch() function. None of the remaining then() function are invoked.
getResultFromServer("Saas")
  .then(function(result){
    // Return value to next then().
    return result.filter((result) => result.city === "Orlado");
  })
  .then(function(resultFromOrlando){
    ui.renderSideBar(resultsFromOrlando);
  })
  .catch(function(error) {
    console.log("Error : " + error);
  })

No comments:

Post a Comment