Monday 17 July 2017

Promises in ES6 for async operations

This article will present a new feature in ES6 which is the Promise object. This object will ease the burden of programming async operations in Javascript. In classic JS building up multiple asynchronous operations has been cumbersome and there is a lot of ceremony to catch exception. This article will describe some simple uses of Promise(s) and provide some code examples.

I will use Plunkr as an editor and Traceur to support ES6 Javascript code. Traceur is a library to provide the necessary ES6 polyfills and shims to allow using ES6 JS code in browsers, regardless of their lacking support of ES6. Of course, more and more browsers support different functionality in ES6 already.

I will also use Jasmine to test out these Promise(s) using Test Driven Development (TDD) library Jasmine.

First off, we need to add in Traceur and Jasmine. I also include jQuery here. You might want to include these libraries with a local copy and not through a Content Delivery Network (CDN). Add first this to your HTML code:


<!DOCTYPE html>
<html>

  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <link data-require="jasmine@2.4.1" data-semver="2.4.1" rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.css" />
    <script data-require="jasmine@2.4.1" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine.js"></script>
    <script data-require="jasmine@2.4.1" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/jasmine-html.js"></script>
    <script data-require="jasmine@2.4.1" data-semver="2.4.1" src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/2.4.1/boot.js"></script>
    <script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
    <script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
    <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
  </head>



After adding in the necessary HTML code we will make use of Jasmine. We also create a simple helper function to return a Promise object to a function that returns a Promise object.


function getPromise(value, delay){
 return new Promise(resolve => {
  setTimeout(() => resolve(value), delay);
 });
}

describe("Promises in Ecmascript 6", function(){
 it("should execute Promise.race with expected result", function (done){
  let promise1 = getPromise('value: 1', 350);
  let promise2 = getPromise('value: 2', 450);
  let promise3 = getPromise('value: 3', 550);

  let fastestPromise = Promise.race([promise1, promise2, promise3 ]);
   // console.log(fastestPromise);
   fastestPromise.then(result => {
   expect(result).toBe('value: 1');
   done();
   }); //then

  }); //it
}); //describe

We use the built in functionality of Jasmine to test out and wait for asynchronous code to complete, passing into the SPEC function (the function named it) the parameter of done. By calling done(); we signal to Jasmin that the asynchronous code should have completed. Jasmin will wait for a specified time and signal a timeout if it does receive the result from the asynchronous operation.

We also here use ES6 arrow functions in the setTimeout method for compact syntax and we use setTimeout to simulate an easy asynchronous operation. Then we build up three Promises by calling the method getPromise. We then use the static method Promise.race which will on a given array of Promise objects return the quickest result. This is in behavior similar to the .WaitAny method in C# Task Parallel Library (TPL) for the happy .Net coders out there.

Moving on, we use the .then method on the Promise.race object (which is a Promise itself) and we use Jasmin's expect method (Similar to Assert in NUnit) and expect that the quickest method "won" the race, since it was the function with the shortest delay passed into the method getPromise and its call to setTimout.

The Promise object in ES6 will be further built upon in ES2017. Here, the await keywords will be added and make Javascript functional asynchronous programming more syntax-like and operational/behavior like much of that in .Net.

Most important, Promises in ES6 makes asynchronous programming and its necessary passing of callbacks and error catching much easier by allowing the programmer to chain multiple asynchronous operations and build asynchronous APIs. Multiple Promises can be passed in, chaining multiple Promises and "paths" of asynchronous operations and multiple async operations can be catched in a single or multiple common error handler with the .catch for error handling and the .then for the chained success function.

You can experiment yourself with the code above using Traceur and Jasmin. I have included a Plunk at the following url:

ES 6 Promises Plunk sample code Important - Note that inside an asynchronous operation we must signal that the async operation is completed. We use the resolve method or static Promise.resolve method to do that. We can also reject the success of the async operation by using the reject method or static Promise.rejec.

The call to done(); is because we use Jasmin as previously described and to support async operations inside a Jasmin TDD spec.

Let us also look at another type of Promises, chaining multiple Promises. We use the Promise.resolve method to build up Promises.

Wednesday 12 July 2017

Using ES6 Generators to implement Where Skip Take

This article will present the use of ES6 Generators to implement in Javascript some handy functions for collections (arrays) that can filter and limit the size of that result. The technique will use the new ES6 generator functions.

ES6 Generators are functions of Ecmascript 6 that let's the programmer take control of iterators using the yield keyword and use custom logic.

We will use Traceur to support ES6 syntax. Traceur is a Javascript compiler in the form of a library. In production you should instead use a transpiler, that rewrites your ES6 syntax into ES2015, which is more supported by current web browsers. One transpiler is Babel.

First off we include Traceur into the Html code:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
        <script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
        <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        
    </head>
    <body bgcolor="teal" style="font-family:Verdana, Courier,Helvetica, Arial">
        
        <h1 style="color:yellow;font-family:Arial">ES6 module demo</h1>



We now have the compiler loaded into our HTML page and can make use of ES6 Generator functions and other ES6 syntax. First lets look at the WHERE function in Javascript. Think of it as WHERE in Linq, we will also use ES6 Arrow functions here, which is an important functional programming concept and syntax that ES6 introduces.


   <script type="text/javascript">

         var where = function* (predicate, collection){
                for (let item of collection){                  
                    if (predicate(item)){                   
                        yield item;      
                    }
                }
            }




We assign where here to the function defined at the right hand side. Note the asterisk (star) here. This is what a generator function looks like in ES6. It must not be mixed with function pointers as in C++, the star here is just to separate generator functions with ordinary functions. On a operational level, generator functions are just like iterators in C# that hey hand off control from the function to the program that calls the functions. Generator functions are usually used in iteration loops, which will be seen later on in this article.

The where function passes in a predicate (an arrow function that returns a boolean which is true or false of course) and if that predicate on the current item of the collection is true, yield will return that item. The sample also uses the of operator of the collection passed in.

Next off, let us look at the take function. This function will take a desired number of the result set and end iteration early if a result set is found. On a very large collection, this is very efficient. Imagine searching a huge collection for a desired item defined by an arrow function and exit early if for example one item is found. Then take(1, mycoll) will return control to the calling program when that item is found.


            var take = function* (size, collection){

            if (size < 1) 
                return;

            let count = 0;

            for (let item of collection){
                yield item;
                count = count + 1;
                if (count >= size){
                    return;
                }
            }
        }



Make note that we end the looping here by doing a return when the amount of items return is the desired size specified. Next off, let us look at the Skip function. We could do a reserve on the passed in collection, and use the take function. Instead the Skip method will use tailored logic to iterate on the passed in collection from start to finish, skipping the specified number of items first.

  var skip = function* (size, collection){
         
            let skippedItems = 0;

            for (let item of collection){
                skippedItems = skippedItems + 1;
                //console.log(item);
                //console.log(skippedItems);
                
                if (skippedItems <= size){
                    continue;
                }
                else {
                    yield item;
                }
            }

        }
The sample HTML code below tests out the JS code above using ES6 arrow functions and ES 6 generator functions on a simple array and looping through with our new powerful functional programming constructs that let us search even huge collections with filtering and skipping or taking the desired result.

         
            var coll = [ "Tammy", "Tom", "Betty", "Marge", "Joey", "Tim", "Jane", "Tommy" ];

            //console.log(coll);
            
            for (let i of take(2, where(n => n.startsWith("T"),coll))){
                   $("body").append("<li>" + i + "</li>");
            }

Next off, we will combing all the uses of WHERE, SKIP and TAKE to both filter and provide paging functionality. Consider this code:


            var coll = [ "Tammy", "Tom", "Betty", "Marge", "Joey", "Tim", "Jane", "Tommy" ];

            console.log(coll);

            let pageSize = 1;
            let pageIndex = 1;
            
            for (let i of take(pageSize, skip(pageIndex*pageSize, where(n => n.startsWith("T"),coll)))) {
                   $("body").append("<li>" + i + "</li>");
            }
                  
Here we use the following to get a PAGE of our result by using the formula:

PAGE_INDEX = TAKE(PAGE_SIZE) of (SKIP(PAGE_INDEX * PAGESIZE) of COLLECTION WHERE Predicate(x)). It is impressive that we can implement Linq like functionality by using ES6 Generator functions in ES6 sticking to ES6 syntax. This promises that Javascript in the future will be a very versatile language when it comes to functional programming. We use Traceur in the meantime to support ES6 syntax in different web browsers. I have included a Plunk in the link below so that you can test this out yourself.

ES6 Generator functional programming sample

Sunday 9 July 2017

Ecmascript 6 Modules in Javascript

Javascript is a programming (or scripting) language known for its wide use. It is mature by the fact that it is used for many years since its creation in the mid 90s. But at the same time Javascript or just JS is immature by the fact that it lacks a lot of features built into the language. This is an observed by the large number of different libraries to add features to JS that programmers using other programming languages take for granted. For example, modules and classes are not something easy to create with JS.
The good thing is that JS is finally evolving in large steps now with Ecmascript 6 or ES6 with a common standard that many browsers vendors can agree upon. There are different ways to run JS code with ES6 features. One can use a transpiler such as Babel that will rewrite the JS code with ES6 scripts into to compatible ES2015 syntax which more browsers support. Or one can use a javascript library that contains polyfills and fills to support ES6 code in browsers. The sample code in this article has been tested with Internet Explorer 11 and is available as a Plunk. The following url contains the running demo:
Plunk with ES6 modules

First in this sample a class called Employee is created. This uses ES6 new class feature.

        export class Employee {

 
 
 constructor (name) {
  //console.log("Constructor of Employee");
  this._name = name; 
 }

 get name() {
  return this._name;
 }

 doWork(){
  return `${this.name} is working`;
 }
}

ES6 classes can export a class and then be imported in other classes and build up modules. The employee class also uses ES6 template string feature. Note that the backtick quote is used and ${..} is used to refer to variables. The next class then imports the Employee class. Note that you must change url here to match your Plunk in the running editor to adjust the session url that Plunkr uses to give unique urls. ES6 can support static urls of course.

import {Employee} from "http://run.plnkr.co/gIljKiTbjZ0IOX8b/Employee.js"
export class Company {


 hire(...names) {
  this.employees = names.map(n => new Employee(n));
 }

 doWork(){
  console.log(this.employees);
  $("body").append("<ul>");
  for (let e of this.employees){
   console.log(e);
   $("body").append(`<li style='list-style-type:circle'>${e.doWork()}` + "</li>");
  }
  $("body").append(">/ul<");
  return 1;
 }
}

Again the class keyword is used to define a class and then exported to be used in another class or module with the export keyword. To import the Employee class the import keyword. The Company class above uses the rest operator (...) to allow passing in an arbitrary number of elements. Then the map operator built into Arrays in ES6 is used to return a mapped array. The use of the let operator is used and also the of operator of iterable collections.
Finally the sample HTML code below is used to define the use of an ES6 module. Here the script tag with the tag module is used.


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
        <script src="https://google.github.io/traceur-compiler/bin/traceur.js"></script>
        <script src="https://google.github.io/traceur-compiler/bin/BrowserSystem.js"></script>
        <script src="https://google.github.io/traceur-compiler/src/bootstrap.js"></script>
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
        
    </head>
    <body bgcolor="teal" style="font-family:Verdana, Courier,Helvetica, Arial">
        
        <h1 style="color:yellow;font-family:Arial">ES6 module demo</h1>
        <script type="module">
        import {Company} from "http://localhost/babeldemo/src/Company.js"
        var c = new Company();
        c.hire("Tim", "Tom", "Betty", "Maggie");
        c.doWork();
        </script>
        
    </body>
</html>

Note that Traceur is a good option to test out ES6 features. In production, using a transpiler such as Babel to create a ES2015 compatible JS code is probably much better since there is a performance cost with Traceur. The reason Traceur is used in this sample is to show how an old browser such as Internet Explorer 11 can run ES6 code with a Javascript library such as Traceur.

To see a compatibility matrix of which browsers supports which ES6, see the Kangax table at the following url:
https://kangax.github.io/compat-table/es6/
With the help of Traceur more browsers can run more feature of ES6 and you can test out and use ES6 in your development or production environments and structure your code with classes and modules for example. Make note that the current state of Javascript module loaders of browsers will be improved in the future. Until then, additional frameworks such as AMD or Require.Js can be used to support module loading in more complex scenarios.