Live data from Hacker News

JavaScript async/await implemented in V8

chromium.googlesource.com

121–130 of 227 posts

Re: JavaScript async/await implemented in V8

#121
post #112

I can't see how wrapping everything in a promise and a try/catch, plus adding async/await is any easier then a callback.

Try/catch is only useful if you want to support promise failure, it's perfectly fine not using it if you know there is no acceptable failures (eg, use try/catch for network operations, not for setTimeout).

Re: JavaScript async/await implemented in V8

#122

I have yet to see a convincing argument that this feature is necessary or even helpful beyond one-liners. The Q promises API, to me, is the right way to reason about asynchrony. Once you understand closures and first class functions, so much about complex asynchronous flows (e.g. multiple concurrent calls via Q.all, multiple "returns" via callback arguments) become so simple. The "tons of libraries" argument doesn't…

Allow me to make both a theoretical and practical argument. It's been said that "callbacks are imperative; promises are functional". It's true. Furthermore, callbacks structure control flow and promises structure data flow. Instruction scheduling is an explicit sequence with callbacks (well, assuming the API calls you back precisely once), but scheduling is an implicit topological sort of the directed acyclic depende…

This is not quite true with regards to promises - one can do

    getY(x)
      .then(returnedY => Promise.all([Promise.resolve(y), zPromise()])
      .then([y, z] => { ...another side effect...; return Promise.all([Promise.resolve(y), Promise.resolve(z), sideEffectPromise()])
      .then([y, z, _] => f(y, z));
Not the cleanest, but you preserve the isolation without relying on polluted variables bleeding into function scope. In addition, one can do proper error handling via .catch as opposed to the brute force unnecessary catchall that is a try-catch.

Re: JavaScript async/await implemented in V8

#123
post #4

The moment I started using async await (with babel) combined with the new fetch API so many libraries got obsolete. Getting data is as easy as: async function main () { try { const res = await fetch('https://api.github.com/orgs/facebook'); const json = await res.json(); console.log(json); } catch (e) { // handle error } } So I am quite happy when this lands in modern browsers asap.

Is the syntax composable? Can I do const json = await (await fetch(https://api.github.com/orgs/facebook')).json(); or do I have to name it?

I don't understand your code. the .json() should be inside the parentheses because you cannot await something that has already been converted from a Promise to a real value. And even in that case that code will be exactly equivalent to the synchronous code because you are awaiting in place the result of the Promise. So, given my very limited knowledge of javascript, I think that probably you can write it moving the .json() inside, but I don't see why you would ever want to do it if you can have the same result without the await boilerplate...

EDIT: got it, you want to do it inside an aync function with some other code after the await, then I think it makes sense in that case.

Re: JavaScript async/await implemented in V8

#124
post #23

Earlier quoted context omitted.

The try and catch inside the async function is also great. Curious though, is using const over let common? I usually use const for imports and module level globals, and let inside functions. I recently got back into javascript, and it's nice to see it flourishing.

The great thing about let and const, for me, is that it gives you crucial information about variables without having to look further down. const should be the default, and if you're going to reassign it, then use let. In most code, you'll use const on the vast majority of variables, and it'll make let assignments stick out, which helps a lot when you're browsing the code or refactoring.

This right here. One of my friends (a more experienced developer) told me at coffee one day, "I use const for everything" which really stuck with me. It really helps make it clear if you need a mutation to have let stand out.

Re: JavaScript async/await implemented in V8

#125

Earlier quoted context omitted.

The try and catch inside the async function is also great. Curious though, is using const over let common? I usually use const for imports and module level globals, and let inside functions. I recently got back into javascript, and it's nice to see it flourishing.

We also favor using const as a default for everything in our team's code. When someone uses let, it's right away obvious that the reference will change. One case that surprised me a bit is that it's correct to use const in for-of loop, e.g. for (const a of arr) {}

I've been using a lot of const function declarations

`const fn = (i) => ...`

Re: JavaScript async/await implemented in V8

#126
post #44

Earlier quoted context omitted.

Probably in an upcoming Node 6 -- they do update the running version with the latest v8 releases IIRC.

That seems like a mistake to me. That would mean code that runs perfectly under, say, 6.5 would not run on 6.1. It should most certainly be a 7.x release.

This is intentional - it's a feature, not a breaking change, although the docs do identify a greater possibility of regressions until LTS. From https://nodejs.org/en/blog/release/v6.0.0/

> The general rule for deciding which version of Node.js to use is:

> ...

> - Upgrade to Node.js v6 if you have the ability to upgrade versions quickly and want to play with the latest features as they arrive.

> Note that while v6 will eventually transition into LTS, until it does, we will still be actively landing new features (semver-minor). This means that there is an increased chance for regressions to be introduced..

Re: JavaScript async/await implemented in V8

#127
post #4

The moment I started using async await (with babel) combined with the new fetch API so many libraries got obsolete. Getting data is as easy as: async function main () { try { const res = await fetch('https://api.github.com/orgs/facebook'); const json = await res.json(); console.log(json); } catch (e) { // handle error } } So I am quite happy when this lands in modern browsers asap.

Can anyone point to a good explanation why this is preferable to cooperative threads (coroutines)? I.e. the above code could easily be written as

  function main() {
    try {
      const res = fetch('https://api.github.com/orgs/facebook');    // yield here
      const json = res.json();                                      // yield here
      console.log(json);
    } catch (e) {
      // handle error
    }
  }
and the runtime would automatically yield this coroutine and let other coroutines run whenever some call blocks.

I guess the only realy difference would be that I would make `await` (and `async`) implicit, similar to how exceptions are handled implicitly in the above snippet (i.e. we don't annotate functions as `throwing` and we don't use an `attempt` statement (analogous to `await`) when calling `throwing` functions).

Edit: Reading various articles, the best explanation is that since the single-threaded nature of JavaScript makes synchronisity implicit (i.e. all code is run in an implicit transaction), it has to make asynchronisity explicit. The alternative would be to have coroutines/fibres (implicit asynchronisity), but with explicit `atomic` blocks (for synchronisity).

C# doesn't provide any synchronisity guarantees, so I guess the motivations there were different (it's really hard (impossible?) to implement fibres efficiently, and even harder to allow for native code interoperability).

Re: JavaScript async/await implemented in V8

#128
Why is "async" keyword needed? Can't JS engine infer from the use of "await" in a function that this function need to be async? I'm using async/await for a while now, and so many times I've introduced bugs in my code because i forget to put "async" in front of the function, or put "async" in front of wrong function. It's simply annoying to go back and put "async" when in middle of writing a function I realise I need to use await.

Re: JavaScript async/await implemented in V8

#129
post #127
post #4

The moment I started using async await (with babel) combined with the new fetch API so many libraries got obsolete. Getting data is as easy as: async function main () { try { const res = await fetch('https://api.github.com/orgs/facebook'); const json = await res.json(); console.log(json); } catch (e) { // handle error } } So I am quite happy when this lands in modern browsers asap.

Can anyone point to a good explanation why this is preferable to cooperative threads (coroutines)? I.e. the above code could easily be written as function main() { try { const res = fetch('https://api.github.com/orgs/facebook'); // yield here const json = res.json(); // yield here console.log(json); } catch (e) { // handle error } } and the runtime would automatically yield this coroutine and let other coroutines run…

It might be something to do with backwards compatibility.

Re: JavaScript async/await implemented in V8

#130
post #128

Why is "async" keyword needed? Can't JS engine infer from the use of "await" in a function that this function need to be async? I'm using async/await for a while now, and so many times I've introduced bugs in my code because i forget to put "async" in front of the function, or put "async" in front of wrong function. It's simply annoying to go back and put "async" when in middle of writing a function I realise I need…

I'd agree with you, and I'm keen to learn the real answer. My guess would be that some initial optimizations can occur without having to also parse and analyze the body of a function, potentially having significant performance benefits to reducing the boot time of a program.
Post reply on HN