The last couple of years have been an exciting time for JavaScript programmers. The TC-39 committee that oversees the ECMAScript standard has added many new features, some of which are syntactic sugar, but several of which have propelled us into a whole new era of JavaScript programming. By itself, the async/await feature promises us a way out of what's called Callback Hell, or the situation we find ourselves in when nesting callbacks within callbacks. It's such an important feature that it should necessitate a broad rethinking of the prevailing callback-oriented paradigm in Node.js and the rest of the JavaScript ecosystem.
Refer back a few pages to this:
query('SELECT * from db', function (err, result) { if (err) throw err; // handle errors // operate on result });
This was an important insight on Ryan Dahl's part, and is what propelled Node.js's popularity. Certain actions take a long time to run, such as database queries, and should not be treated the same as operations that quickly retrieve data from memory. Because of the nature of the JavaScript language, Node.js had to express this asynchronous coding construct in an unnatural way. The results do not appear at the next line of code, but instead appear within this callback function. Further, errors have to be handled in an unnatural way, inside that callback function.Â
The convention in Node.js is that the first parameter to a callback function is an error indicator, and the subsequent parameters are the results. This is a useful convention that you'll find all across the Node.js landscape. However, it complicates working with results and errors because both land in an inconvenient location — that callback function. The natural place for errors and results to land is on the subsequent line(s) of code.
We descend further into callback hell with each layer of callback function nesting. The seventh layer of callback nesting is more complex than the sixth layer of callback nesting. Why? If nothing else, it's that the special considerations for error handling become ever more complex as callbacks are nested more deeply.
var results = await query('SELECT * from db');
Instead, ES2017 async functions return us to this very natural expression of programming intent. Results and errors land in the correct location, while preserving the excellent event-driven asynchronous programming model that made Node.js great. We'll see later in the book how this works.
The TC-39 committee added many more new features to JavaScript, such as:
- An improved syntax for Class declarations making object inheritance and getter/setter functions very natural.
- A new module format that is standardized across browsers and Node.js.
- New methods for strings, such as the template string notation.
- New methods for collections and arrays — for example, operations for map/reduce/filter.
- The const keyword to define variables that cannot be changed, and the let keyword to define variables whose scope is limited to the block in which they're declared, rather than hoisted to the front of the function.
- New looping constructs, and an iteration protocol that works with those new loops.
- A new kind of function, the arrow function, which is lighter weight meaning less memory and execution time impact
- The Promise object represents a result that is promised to be delivered in the future. By themselves, Promises can mitigate the callback hell problem, and they form part of the basis for async functions.
- Generator functions are an intriguing way to represent asynchronous iteration over a set of values. More importantly, they form the other half of the basis for async functions.
You may see the new JavaScript described as ES6 or ES2017. What's the preferred name to describe the version of JavaScript that is being used?
ES1 through ES5 marked various phases of JavaScript's development. ES5 was released in 2009, and is widely implemented in modern browsers. Starting with ES6, the TC-39 committee decided to change the naming convention because of their intention to add new language features every year. Therefore, the language version name now includes the year, hence ES2015 was released in 2015, ES2016 was released in 2016, and ES2017 was released in 2017.