Live data from Hacker News

JavaScript async/await implemented in V8

chromium.googlesource.com

21–30 of 227 posts

Re: JavaScript async/await implemented in V8

#21

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…

You'd like Tcl and various Perl libraries. Mojo (Perl event loop among other things) in particular has a very nice, straightforward event flow quite reminiscent of Q.

async/await looks nice but doesn't scale. As soon as you have to do something other than wait for a callback it falls apart.

Re: JavaScript async/await implemented in V8

#22

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…

The think about using async/await its to write less code, make it much simple and makes also easy to try/catch errors.

The think I don't like about promises its that you need to write a lot of lines that you could avoid with async/await, i.e:

  new Promise(function(success, failure){
    db.fetch('sql...', function(err, data){
      if (err) failure(err)
      else success(data)
    })
  })
VS

  var data = await db.fetch('sql...')
Also if you concatenate with then

  promise.then(function(done, args){
      try {
        db.fetch('sql...', done)
      } catch(e) {}
    })
    .then(function(done, args){
      try {
        db.fetch('sql2... {args}', done)
      } catch(e) {}
    })
    .then....
VS

  try {
    var data1 = await db.fetch('sql1...')
    var data2 = await db.fetch('sql2... {data1}')
  } catch(e) {}
btw its just pseudocode but you get the main idea

Re: JavaScript async/await implemented in V8

#23
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.

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.

Re: JavaScript async/await implemented in V8

#24
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.

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.

const is more declarative as you can immediately tell that the data isn't going to change throughout the duration of the program (although technically you can change the data, just not the reference).

Re: JavaScript async/await implemented in V8

#25
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?

You probably can, but you may as well just do this instead:

    const json = await fetch('https://api.github.com/orgs/facebook').then(res => res.json());

Re: JavaScript async/await implemented in V8

#26

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 dependency graph of promises.

Sometimes, when it comes to side effects, implicit scheduling is less than ideal. You need specific things to happen in a specific order. The solution is to introduce data dependencies to force a particular schedule. This is precisely what is done by monads in Haskell. However, unlike Haskell, JavaScript doesn't have "do" syntax, so there's no convenient notation for a nested chain of bindings.

The result of not having monadic binding syntax is that you wind up with some funky nested chain of getY(x).then(y => y.then(z => z.then(.... OR you have to declare variables up top, flatten your then blocks in to a promise chain, and often ignore intermediate values:

    let y, z;
    getY(x)
    .then(returnedY => { y = returnedY; return zPromise(); )
    .then(returnedZ => { z = returnedZ; return ......; }
    .then(......another side effect.....)
    .then(_ => f(y, z))
async/await neatly eliminates this problem by reusing the traditional coupling of data flow dependencies with first-order control flow dependencies.

Practically:

    let y = await getY(x);
    let z = await getZ(y);
    ......another side effect....
    return f(y, z)

Re: JavaScript async/await implemented in V8

#27
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.

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.

IMHE, const is the generally the default and let is the exception.

Re: JavaScript async/await implemented in V8

#28
post #16

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…

> (e.g. multiple concurrent calls via Q.all, multiple "returns" via callback arguments) How about: async function main () { try { const responses = await Promise.all([ fetch('https://api.github.com/orgs/facebook'), fetch('https://api.github.com/orgs/facebook') ]); const jsons = await Promise.all(responses.map(res => res.json())) } catch (err) { console.log(err) } } I think this is pretty clear and not needing any lib…

Just to be picky, but I believe you would be better off with this:

    async function main () {
      try {
        const jsons = await Promise.all([
          fetch('https://api.github.com/orgs/facebook'),
          fetch('https://api.github.com/orgs/facebook')
        ]).map(promise => promise.then(res => res.json()));
      } catch (err) {
        console.log(err)
      }
    }
This way, if one response was much quicker than the other, you could begin sending it through the `res.json()` portion immediately, instead of waiting for both responses to return before continuing.

Re: JavaScript async/await implemented in V8

#29
Kinf of OT, but can anyone share their experience about using Babel's async/await in production instead of regular Promises?

I'd love to hear about people who have used it in large and complex projects, from a debugging standpoint.

As of now, using Bluebird (with its source in a different, blackboxed script), it is possible to follow the code execution through the event loop with async debugging, in a very elegant and enjoyable fashion.

I find async/await much more appealing when coding, but I'm worried about quality of life when hardcore debugging, as in my current project it can make me waste hours at a time when something if completely fringe happens.

Post reply on HN