Photo by Luca Bravo _ Unsplash

Native JavaScript promises – part2 : Effective use

Syntax

A promise can be seen as a constructor that wraps a “try-catch” around the asynchronous code. Here is the syntax of a basic promise (more syntax variation on MDN):

/**
 * Basic promise syntax with 3 states: pending, success and failure
*/
new Promise(function(resolve){
   console.log('Still in process (pending)');
   resolve();
}).then(function(){
   console.log('Resolved (success)');
}).catch(function(){ 
   console.log('An error happened (failure)');
   //Dealing with the error here!
}); 

 

Use case: Acting on the page before it fully loads

A promise can be used to “spy” on the document and create an action at a specific moment. Suppose we want something done on the page before sub resources are loaded (images, stylesheets, …), we can create a promise that resolves only when the page reaches a precise loading state and then call and action when that promise resolves.

/** 
 * Create a promise that resolves only when the document 'ready state' 
 * is not on "loading" and call an action when that promise resolves
 * We assume: 
 * doSomethingOnTheDOM() updates the DOM with whatever feedback we choose
*/ 
//Wrap an event listener for readystatechange in a Promise.
function ready() { 
  return new Promise(function(resolve){
    function checkState (){
      //Only resolves if document is not 'loading'
      if(document.readyState !== 'loading'){
        resolve(); 
      }
    }
    //Check ready state when 'readystatechange' event fires
    document.addEventListener('readystatechange', checkState);
    checkState();//also checks ready state immidiately
  });
};//ready()

//Update the DOM only when the promise resolves. 
ready().then(doSomethingOnTheDOM);

 

Fetch API, a real game changer:

The Fetch API makes the process of fetching resources a breeze by providing an elegant interface that encapsulates native JavaScript Promises and handle results and callbacks (checkout also David Walsh article).

In the following example, we won’t worry about writing the XHR request, nor  parsing the resulting resource ourselves.

//Outpout something on the DOM
//Uses fetch (fetch API) to make and XHR request and return a promise
function get(url) {
  return fetch(url); //fetch assumes the method is 'get'
}

//Performs an XHR request and returns a parsed JSON response.
function getJSON(url) { 
  return get(url).then(function(response){
    //Returns a promise that resolves with a JSON object.
    return response.json();
  });
}

//When document is ready ...
  getJSON('../data/file.json')
  .then(function(response){
    doSomethinOnTheDOM(response);
    return response; //can be reused for chaining
  });
//When document is ready ...

 

Conclusion:

We’ve just seen a basic syntax of Native JavaScript Promises and looked at one possible use case where a promise is used to target a precise loading stage of the page. We’ve finally looked at a simple use of the Fetch API.

Next time, we’ll look at native JavaScript promises’ chaining and error handling.

 

Published by

Eric Njanga

Web front-end developer passionate about finding the most efficient workflow for creating the most effective user-interfaces. His dream is to become a front-end instructor. wlayouts@gmail.com / https://ca.linkedin.com/in/ericanjanga