About the Author:

Decorating (your Javascript) for Fun and Profit

February 20th, 2017

Sometimes you need to get “meta”. What if you could tell a variable that any time it changes, it should automatically report that change to a log file, without you having to write code to do it? What about identifying a function should be called by a web server whenever a particular URL pattern is matched? Or maybe, as with tools like mobX, you want to have functions be invoked only when the variables they reference change. These could radically simplify the amount of “communication” code that you need to write, and more can concentrate the responses to such changes in a consistent manner rather than force piecemeal edits. This is the role of decorators, perhaps one of the most important capabilities to emerge from the ES2017 upgrades. This post will give a quick primer on ES2017 Decorators.

Decorators

Decorators are familiar to people who work with Babel, but these (and the associated code constructs that these enable, such as those used by Mobx or similar libraries) have yet to make their way into broad implementation natively in most browser engines. As such, you will need to use Babel as a preprocessor for any of the following (or use the ES2015 implementation, discussed below).

Functions are objects. This single fact opens up an entire world in which functions can be “decorated” in various ways in order to expose certain functionality. A decorator, in this context, is a function that wraps around another function in order to provide information to some other process. Decorators differ from ordinary functions in that they do not ordinarily change the result of the function, but rather invoke some additional action when the functon is called, such as adding an entry in a log or indicating that a given parametric class property is observable or not.

The use of such decorators has been around for awhile, and collectively is known as aspect-programming (or, sometimes, metaprogramming). They are, however increasingly showing up in Javascript typically at the point where classes and associated methods are defined. Starting with ES2016, transpilers such as Babel used the @ symbol to indicate such a decorator.

A (relatively) simple example of a decorator might be something like a @log decorator, which is used to identify when a given method is called in a class, along with the arguments applied to that method.

class Mat {
 @log
 add(a, b) {
  return a + b;
 }
 @log
 subtract(a,b){
  return a - b;
 } 
}
var m = new Mat();
m.add(2,3)
m.subtract(2,3)

The two functions add and subtract do exactly what you would expect them to do. However, in both cases these methods have the @log decorator placed on it, which serve to add a log event every time each of these methods is invoked:

Calling "add" at Thu Dec 22 2016 19:02:16 GMT-0800 (Pacific Standard Time) with [2, 3]
Result = 5
Calling "subtract" at Thu Dec 22 2016 19:02:16 GMT-0800 (Pacific Standard Time) with [2, 3]
Result = -1

The log file gives the name of the method and the parameters being passed, along with the time stamp for when the method was called.

In order to create this particular bit of magic, it’s necessary to define the log decorator previously. This would likely be loaded in via an import of some sort from an established library module.The @log decorator itself is defined as follows:

function log(target, name, descriptor) {
 var oldValue = descriptor.value;

 descriptor.value = function() {
  console.log(`Calling "${name}" at ${new Date()} with arguments `,arguments);
  var output = oldValue.apply(null, arguments);
  console.log(`Result = `,output);
  return output;
 };

 return descriptor;
}

Here, the log function is passed a target (the specific function object, the name of that function, and a descriptor that provides relevant information about the function, such as its passed parameters). The old value of the descriptor (which is a function) is temporarily cached in a variable, a log description is sent to the console, and the function is then invoked with the arguments metavariable passed in through the context of the original function (arguments is an array-like object that holds the arguments of the initial calling function).

Given that you have the function and its associated arguments (and with some work the binding class or prototype) this can not only get information but can also be used to populate other control structures. As an example, certain libraries such as Mobx make use of decorators to designate @observable variables. When the value of these change, notifications can be passed back to a reference broker object which will then update items that subscribe to that observable “variable”, without having to write code into the setter/getter directly.

This has incredible utility for React and similar libraries, as these will change UI only when observed variables change. Indeed, this is where the true power of decorators come in: the act of invoking methods that can be passed on to specialized objects without the original author of those methods needing to know the internal mechanisms involved.

About the Author:

A Primer on ES2017 Async and Await

February 11th, 2017

As the year 2016 draws to a close, attention is now turning to what will emerge from 2017, with Javascript as much as anything. The language is undergoing a massive evolution now, increasingly taking on characteristics that make it attractive as a full stack environment.

The ES2017 (ES8) stack is already now being implemented in both Node and several modern browsers, addressing many of the more complex issues of web development including better ways of dealing with asynchronous coding. This piece will give a short primer on working with the new ES2017 features Async and Await.

Async and Await

More than almost any other language, JavaScript has struggled with a seemingly simple problem – how do you keep interfaces responsive when you have to fetch (or send) contents over a data socket across the web? The first solution to that was to write polling routines to activate a setTimeout or setInterval call, then returning a flag state that indicated a given transfer was complete. With the advent of AJAX calls in the late 1990s, this functionality was relegated to a specific object, the XmlHttpRequest object, and later eventually subsumed in jQuery oriented ajax(), get() and post() functions.

This, in turn, introduced the notion of asynchronous callbacks into Javascript – passing a function as an argument to another asynchronous function with a predetermined set of parameters. Such callback functions would then be invoked once either the data had completed transferring or an error had occurred (in which cases a different function would be passed for cleaning up the action).

One problem became quickly evident with this approach. The resulting callback functions themselves often needed to push the resuting data to another function, which would require another callback, and eventually the resulting code became hideously deep and complex.

The first solution to this problem was to implement a construct called a promise. A promise was a deferred callback object that was implemented initially in ES2015, then refined in ES2016. A promise was a wrapper object that held the callback function(s). When the invoked asynchronous function completed, then it would return a resulting object that could then be passed into a new promise, resulting in a promise chain.

This construct was better, but could still end up being too verbose, especially when what you needed was data from multiple sources independently. The async identifier, along with the await keyword, is the ES2017 solution to that particular problem. As a simple example , first create a promise, in this case a promise of a function that returns a value after a specified number of seconds:

function resolveAfterInterval(x,t) {
 return new Promise(resolve => {
  setTimeout(() => {
   resolve(x * x);
  }, t * 1000);
 });
}

Here, the function resolveAfter interval takes two parameters, a value that will be squared, and the time in seconds. The function creates a new promise around a function (internally called resolve()) that in turn calls a setTimeout function. The resolve function is itself just a placeholder that returns whatever is passed into it, here the square of the number. The t parameter in turn is used to set the number of seconds before the function returns.

The await keyword is applied to a function or variable to indicate that it should await the completion of the promise before passing the results of that promise. If the await is passed on the variables, then the return statement is invoked once the last of the variables are known, here at three seconds.

async function distance1(x) {
 var a = resolveAfterInterval(20,2);
 var b = resolveAfterInterval(30,3);
 return Math.sqrt(Math.pow(x,2) + Math.pow(await a,2) + Math.pow(await b,2));
}
distance1(10).then((v)=>console.log(v))

Note that that await serves very much the same purpose in an asynchronous function that yield does for a generator (and they use many of the same mechanics under the hood). Here, the output will return only once the longest promise’s interval completes, at 3 seconds.

This is a little different from the situation where the awaits is applied to the functions themselves:

async function distance2(x) {
 var a = await resolveAfterInterval(20,2);
 var b = await resolveAfterInterval(30,3);
 return Math.sqrt(Math.pow(x,2) + Math.pow(a,2) + Math.pow(b,2));
}
distance2(10).then((v)=>console.log(v))

In this example, the first await won’t return until after two seconds, while the second await won’t return until three seconds after the first one is satisfied (or five seconds after the code starts). This occurs because the await acts like an asynchronous block – in the second example, the following statement won’t occur until after the initial function’s promise is returned, but in the first example, the return statement executes once the variables have been assigned.

Using await is actually quite valuable in situations where you want an action to occur once all of the data is available from all sources, but not a moment after. Ordinary chaining of promises is almost as bad as synchronous processing (since you’re dependent upon waiting for one promise to complete before a second one can start, as the second example shows), but with the async and awaits keywords you can reduce this wait only to that of the longest single process.

Summary

ES 2017 is the culmination of an upgrade cycle that has significantly changed the flavor of the Javascript language, bringing it more in line with contemporary functional languages such as Haskell or Scala. The language that has emerged is becoming quite powerful and expressive. At the same time, there is a huge amount of innovation occurring with various libraries such as mobX, React and elsewhere, and these in turn are becoming grist for strengthening the core language to better reflect these innovations.