What's the synax `async/await` in zombiejs code? - javascript

When I read the source code of Zombie.js, I found async/await keyword:
before(async function() {
await browser.visit('/streaming');
await browser.pressButton('1');
});
https://github.com/assaf/zombie/blob/41807a39c7aa1a13c4ef51575e0d581be96175bc/test/event_source_test.js#L60
Why can it use such keywords? What is the behaviour of the code? I tried to find some clue from the codebase, but not lucky

If we check out the gulpfile used to build that project, we can see that the source is piped through babel.
gulp.task('build', ['clean'], function() {
return gulp
.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(babel({
experimental: true,
loose: 'all',
optional: [
'bluebirdCoroutines',
'runtime'
]
}))
});
Babel is a transpiler which allows you to write ES6+ code and transpile it back to ES5.
Babel will turn your ES6+ code into ES5 friendly code, so you can start using it right now without waiting for browser support.
If we check out the docs on Babel's site, we can see that in the ES7 section of the experimental section, there is an implementation for asyncFunctions.
These keywords are part of the ES7 specification, but they haven't stabilised. Hence them being included as experimental features of Babel.
In simplified terms, an async function will allow you to await a call which returns a promise.
async function() {
// flow will be suspended here until
// the promise returned by someFunction is resolved
await someFunction()
}
ES6 will include what are known as generators, which do a similar thing, but aren't specific to promises. You might start seeing the yield keyword around, or functions declared like this function* () {}. They are what's known as generator functions.
There is a particularly good article from PouchDB which explains a real world use case for these features.

Those keywords aren't available in EcmaScript 5, but are proposed for EcmaScript 7 (the version coming after the upcoming version 6). Right now you can use Babel to transcompile ES6 and some ES7 code into ES5, with some exceptions (notably proxying since it's not possible within ES5). Specifically for this, you can reference Babel's experimental features, specifically Stage 1, es7.asyncFunctions.

It is a new feature planned for ES7 that depends on promises and generators.
Why can it use such keywords?
Beacause they transpile the code with Babel.
What is the behaviour of the code?
It basically means the following in continuation passing style:
before(function() {
browser.visit('/streaming', function() {
browser.pressButton('1');
});
});

It's one of the best things to ever come to JavaScript besides modules and classes. Check out these two articles and library to get an feel for the power:
http://jlongster.com/Taming-the-Asynchronous-Beast-with-CSP-in-JavaScript
http://pouchdb.com/2015/03/05/taming-the-async-beast-with-es7.html
https://github.com/dvlsg/async-csp
Additionally, a search for "javascript async await" will surface some more good articles and examples.

Related

nightwatch-cucumber ES6 --- nightwatch JS ES5

I've read that nightwatch does not support ES6. Fair enough.
However, the documentation for nightwatch-cucumber
Looks like it uses ES6 (arrow functions) on the steps it defines as examples.
My question is: Is it possible to use ES6 on the cucumber steps and ES5 on the page objects for nightwatch? Or should I stick to ES5 for everything?
Yes I was able to write my cucumber steps in ES6 and my page objects in ES5. However it might be better to stick to ES5 to have consistency + I did notice I would get some strange failures (rarely) when using:
Given('Go to Site', () => client.url('https://google.com'));

Syntax error, node.js with the following "Object.keys(colors).forEach((code) => " [duplicate]

Is Node.js supporting => function keyword alias already? If yes, starting from which version? How to enable this language extension?
(function() { console.log('it works!') })()
Becomes
(() => { console.log('it works!') })()
In short: yes, arrow functions are reasonably well supported in Node.js since version 4.4.5.
Completely correct support starts with version 6. Initial support was introduced as far as v0.12 but is was very incomplete and disabled by default until v4.0 when it got better. See Node's ES6 compatibility table for details: http://node.green/#ES2015-functions-arrow-functions.
The syntax you're referring to is "arrow function" syntax. It is a feature of ECMAScript 6, also known as "Harmony". The ES6 standard is now finalized, but engines are still implementing its new features.
The V8 now has arrow function support. Node runs on the V8 engine, but it can take some time for Node to incorporate the latest version into its code base.
Whenever it is added, it might possibly be enabled only via a --harmony command-line flag.
You can follow this issue: https://code.google.com/p/v8/issues/detail?id=2700
Currently (as 02.05.2014) arrow functions have been implemented and waiting until this functionality will be landed in v8: https://codereview.chromium.org/160073006/
After then we'll need to wait, until v8 version with arrow function would be integrated into Node.JS. You can follow Node.JS changelog there: https://github.com/joyent/node/blob/master/ChangeLog (search for "v8: upgrade to ....")
kangax's compatibility tables can keep you up-to-date with what is currently available in Node.
Experimental features can be enabled using the instructions on this page:
All shipping features are turned on by default on Node.js
Staged feature require a runtime flag: --es_staging (or its synonym, --harmony)
In progress features can be activated individually by their respective harmony flag (e.g. --harmony_destructuring) but this is highly discouraged

How to get rid of editor’s error for object.key

I have the following code that basically gets some JSON data, looks for the keys with "servergenre", and saves the results in an array.
This is a follow up of this question.
let result = [];
Object.keys(data).forEach( key => {
if(/servergenre/.test(key)){
result.push(data[key])
}
});
Even though the code is working correctly, in some editors it raises syntactic errors:
"key": unsolvable variable or type key
"=>": expression expected
"if( / server...": formal parameter name expected
")){": , expected
"});": statement expected
Here is an image to show you where the errors are:
As I said the code is working fine, I just need it to be fixed or another approach to get rid of the errors.
Furthermore, many compressors and minifiers do not support this bit of code. So I can’t minify it.
Thanks in advance.
ES2015, formerly known as ES6, is a more recent version of JavaScript, which introduces features such as the => syntax for functions you are using.
Not all features of ES2015 are fully supported in all browsers, so many people who use it pass it through a compiler (“transpiler”) first to convert it to ES5, which is supported by all browsers. Babel is one such transpiler. But if you are only targeting newer browsers, that would explain why the => syntax is working for you.
You just need to change your editor settings to understand that syntax. Exactly how you do that depends on what text editor you are using. It could be that your editor's built-in JavaScript mode doesn't know how to read ES2015 syntax, and you need to either upgrade your editor or install a third-party plugin that provides an updated error-checker. Or it could be that your editor supports both ES5 and ES2015, and it thinks you are trying to write your project only in ES5. In this case you just need to go to the settings and tell your editor that you mean for this project to use ES2015 (or ES2016, which is currently the most recent version).
Fat arrows are ES6 syntax. If that causes trouble, just write good old ES5 :
let result = [];
Object.keys(data).forEach( function(key) {
if(/servergenre/.test(key)){
result.push(data[key])
}
});

Destructuring in ES6. Should I worry?

Experimenting with destructuring and found that the same code works on stackoverflow and not Codepen (toy gets "undefined"): http://codepen.io/tsalexey544/pen/VjWxmm?editors=0010#
What does it mean? should I worry when using destructuring in my projects?
let obj = {
species: "Cat",
// toy: "ball",
}
function whatDoTheyDo ({species, toy = "ball"}) {
return `The ${species} playes with a ${toy}`
}
document.write(whatDoTheyDo(obj));
You just need to set the Preprocessor to babel in CodePen, otherwise it will use standard ES5, where destructuring is not supported.
If you want to use ES6/ES7 features you have to "transpile" your code back to ES5 using certain tools such as Babel. Some browsers already support some ES6 features, but full support is still somehow spotty.
Edit - To answer your question: YES, you should worry about serving valid ES5 code, since ES6 is not yet fully supported. At the very minimum you should feed your code to Babel and publish the resulting code, but I strongly suggest looking it Webpack and going for a full toolchain

How can I use decorators today?

I see decorators being used today already in some javascript code. My question is really two fold.
First:
If decorators have not even been finalized how is it possible to use them in production code, today? Won't browser support be non-existent?
Second:
Given it is possible to use it today, as some open source projects would suggest, what's a typically recommended setup for getting decorators to work?
You're right, ES2016 decorators are not yet part of the spec. But it doesn't mean we can't use it today.
First let's take a step back and go over "what is a decorator". Decorators are simply wrappers that add behavior to an object. It's not a new concept in javascript (or programming in general), it's actually been around for a while...
Here's a basic example of a decorator that checks permissions:
function AuthorizationDecorator(protectedFunction) {
return function() {
if (user.isTrusted()) {
protectedFunction();
} else {
console.log('Hey! No cheating!');
}
}
}
Using it would look like this:
AuthorizationDecorator(save);
You see all we're doing is simply wrapping up some other function. You can even pass a function through multiple decorators each adding a piece of functionality or running some code.
You can even find some old articles explaining the decorator pattern in javascript.
Now that we understand decorators are actually something we (javascript community) were always able to do, it probably comes as no shock that really when we utilize ES2016 decorators today they are simply just being compiled down to ES5 code hence why you maintain browser compatibility. So for the time being it is simply syntactic sugar (some really sweet sugar I might add).
As for which compiler to use to convert your ES2016 code to ES5 code, you have some choices: Babel and Traceur are the most popular.
Here's further reading on Exploring ES2016 Decorators.
#Class decorators support can be enabled in Babel/Traceur
Babel:
$ babel --optional es7.decorators
Source: Exporing ES7 Decorators - Medium
Traceur:
traceurOptions: {
"annotations": true
}
#Property decorators are not supported
...and since each #Property provides a unique functionality, each requires a different approach to desugaring in ES6/7.
Here's how you use #Inject:
Typescript
exports class ExampleComponent {
constructor(#Inject(Http) http: Http) {
this.http = http;
}
}
ES 6/7
exports class ExampleComponent {
constructor(http) {
this.http = http;
}
static get parameters() {
return [[Http]];
}
}
Source: https://stackoverflow.com/a/34546344/290340
Update:
It looks like Babel changed the way decorators are configured and the article is out-of-date. Here's a link to the new approach.
In short; yes you can use #Class decorators in ES6/7; no property decorators aren't supported in ES6/7 so you'll have to use workarounds.
There are some solutions to use decorators:
babel - an es next to es5 compiler with support of decorators.
traceur - another es next to es5 compiler by google.
typescript - a typed superset of javascript language that supports decorators.
There are some difference how these tools transpile a "modern" javascript to an older one so you can explore it if needed as they have online playgrounds.

Categories

Resources