Promises are one of the most valuable additions in world of Javascript. Promises are the way to handle asynchronous javascript to avoid nest callbacks.
Asynchronous pattern is more common and vital for moving to advanced web programming. But asynchronous programming is challenge to work in Javascript. To make life easier, DOJO and Jquery have introduced promises with ECMA5 support.
Traditional JavaScript callbacks work very well up to a point, but we run into problems when we’re waiting for multiple conditions to be met. Anyone who has used Node.js will be familiar with the concept of callback hell:
One pattern is a promise, which represents the result of a potentially long running and not necessarily complete operation. Instead of blocking and waiting for the long-running computation to complete, the pattern returns an object which represents the promised result.
Promise leverage a pattern which represent the result of long running and everlasting operation. Instead of blocking single threaded javascript process and waiting for ever running computation to complete, promises pattern return a object reference which represents the promised result.
At any moment in time, promises can be in one of three states: unfulfilled, resolved or rejected.
You can design a method on promised object and then add handlers for resolved and rejected states.This function returns another promise object to allow for promise-pipelining, enabling the developer to chain together async operations where the result of the first operation will get passed to the second.
Bootstrapping Promises Code
Code snippet below initiates promised object use then to perform action on complete and handler on covering actions to be taking on success and failures.
Using a Promise states
Promise can stay in three states :
pending, resolved and rejected
Let us create a promise, see snippet below, and here since we initiated promise but it doesn't do anything, clearly our promise state becomes
Pending
here.
We can use then() method to handle other promised state like resolve for success and rejected for failure.
Injecting Javascript Dynamically to WebPage with Promises
While developing application and libraries in Salesforce, often we countered scenarios where we need to dynamically inject custom javascript on header of the page and might need to perform a order of load. In few of the cases, like injecting map application on the page, we need jquery, map library in a certain order and only show success when promises is loaded in an order. So I am sharing some of the code snippets.
In the snippet below, we call reject function to handle callback on failure and similarly resolve method on success.
Injecting Javascript in Google Way
Google uses smarter script to inject script on any page, here is wrapper function around it with promises
Injecting Javascript in Facebook Way
Facebook rather look for script with and Id, avoid inject duplicate script and here is wrapper function around it with promises
Loading Promises in Series
Now this is more interesting, if we have multiple libraries to load on DOM build, we can simply make minor modification of code to inject them in specific order.
Simply call method we designed about this fashion, show in snippet below
Loading Promises in Parallel
This approach will allow the process to load all in parallel instead of waiting for one return to invoke another, there are two static method available that can help you achieve that.
Promise.all and Promise.race are static methods that each take an Array of Promises as an argument, returning a new Promise. Both methods will watch the Array but with one important difference; Promise.all will resolve when all of the Promises in the Array have resolved, whereas Promise.race will resolve as soon as any one Promise in the Array has resolved.
Lets modify our first promise code a bit to accomodate this change.
Using Promise Loader in Visualforce Page
In Salesforce, here I am injecting all required static-resources can be injected by local static resource or via CDN. Here I am injecting all needful scripts, in series on a visualforce pages, before the DOM is built, which uses 'Windows.Paint()' method.
Using Pure .loadScript
Simply Using
.when()
method to load script with promises
Utility Method to Loading Array of Scripts;
I improved and wrote a utility method that loops through script array inject scripts
This can be used to call multiple script in loop like this
Also, if any of the scripts fail to load, the fail handler will be called, and subsequent scripts will not be loaded
Using YepNope.js
YepNope is an asynchronous conditional resource loader that's super-fast, and allows you to load only the scripts that your users need. Scripts with the same url won't execute twice, but their callbacks fire in the correct order and also can be use
Using YepNope.js to Load CSS
Q.Js : A tool for creating and composing asynchronous promises
Q.js is neat wrapper library written to handle asynchronous promises, we have been using for couple of our projects and by far it neat and fancy library written to simplify readability, ease of code.
Using Q.Js I wrote a script snippet that uses q.js to dynamically injects script on the page, this script run on every page load.
Using jQuery to asynchronously load script, similar to promises
jQuery can also be used to load synchronously but without promises and similar methods.