await-keyword is taken from the newer versions of C# and VB.NET.
It's job is to pause the execution of a piece of code untill new data is availible,
and then continue off where it left.
This results in the ability to write async functions very easily without the need for callback-nesting.
For instance, let's asume we have a "magic" function called
load whos task it is to
perform a simple xhr-request and callback when the data is availible.
getUserusername passwordgetGroupsuseridcbuser: usergroups: groups;;;load'/getUser'username: usernamepassword: passwordifdatasuccesscbdatauser;elsecbnull;;load'/getGroups/' + userIdifdatasuccesscbdatagroups;elsecbnull;;
As you can see, there's a lot of nesting of functions, and it's not always
easy to understand what is going to happen and in what order. People who are
the user will be logged in immidiately, which isn't the case because our
(here ofcause I assume that the load-function has been written in such a way that
it is usable with the await-keyword and not just callbacks as in the previous
example, more on that later).
var user = await getUserusername password;var groups = await getGroupsuserid;returnuser: usergroups: groups;var data = await load'/getUser'username: usernamepassword: password;ifdatasuccessreturn datauser;elsereturn null;var data = await load'/getGroups' + userId;ifdatasuccessreturn datagroups;elsereturn null;
The second new feature is the
yield-keyword. The yield-keyword works in certain ways
almost like the
await keyword, with the exception that instead of waiting for
whatever you pass after the
yield-keyword it is returned to the calling function.
yield-keyword is simply put used to create generators (or iterators). A simple
example illustrates best how it works:
yield 1;yield 2;yield 3;var iter = testGenerator;console.logiternext; // outputs 1console.logiternext; // outputs 2console.logiternext; // outputs 3console.logiternext; // throws StopIteration
yield you can easily create functions that have no end, because only the data you
request is generated. For instance, one can create a simple fibionacci-generator like this:
var a = 1 b = 0;whiletrueyield a;b = a + b;yield b;a = a + b;
for..of-loop only works on iterators or objects that have the same signature.
for..of to loop though all the values generated from a generator. For instance,
if you take the function
runTest created in the previous section, you could
rewrite the code to this using
forvar n of testGeneratorconsole.logn;
continue works as one would expect, so to print all the fib-numbers less than 100
you could do this:
forvar n of fibifn > 100 break;console.logn;
function-syntax is fairly straight forward. The valid forms are as follow
(all of these are expressions):
1. <identifier> => <expression>2. <identifier> => <statement>3. (<arguments>) => <expression>4. (<arguments>) => <statement>
<arguments> is a comma-separated array of 0 or more identifiers. If any of the variants that
ends in an expression is used, said expression is automatically transformed into a returnstatement.
Here are some samples:
var add = a b => a + b;return => itm;loaddata =>// do stuff with data;
Generator-expressions are an advanced feature that can be used to combine and filter generators. They work similar to list-comprehensions in Python (with the exception that you can't use them on lists). Generator-Expressions expand to for..of loops inside a anonymous lambda internally and are simply syntactic sugar for just that. For instance, the expression
(x * 2 for(x of countTo(10)) is exactly the same as writing
() => for(var x of countTo(10)) yield x;. Weather to use the first one or the last one is a matter of preference.
It is also possible to chain several for..of expressions together. For instance if you had a grid of some kind with cells and rows and wanted to enumerate them you could do something like this:
var cellsIterator = cell forrow of getRows forcell of rowgetCells;
It is also possible to add a single if-statement to the end of the chain to filter out values. For instance, to get every second number from 0 to 10 one could do something like this:
var numIterator = n forn of countTo10 ifn % 2 === 0;
This simply corresponds to the iterator
var numIterator =forn of countTo10ifn % 2 === 0yield n;;