Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

The default way promises are used is now async/await. `.then()` should not be introduced as anything more than 'you may find this in older codebases'.


> The default way promises are used is now async/await. `.then()` should not be introduced as anything more than 'you may find this in older codebases'.

No, because you might have to write explicit promises in the browser with async API that are callback based.

You need to understand how promises work to use async/await at first place anyway.

Just like it's better to understand how prototypal inheritance works in JS BEFORE even using a single class declaration.


"Just like it's better to understand how prototypal inheritance works in JS BEFORE even using a single class declaration. "

About that, does JS class inheritance now work like classes in java for example? Or is it still just syntactic sugar for the prototype inheritance? By your wording, I assume the later?


Correct. It's still prototype based. Thus making the class keyword actually MORE confusing for people from other languages, IMO.



Wow. I was hoping, at some point things would improve a bit.


Agreed. I find myself using a pretty small subset of the language which definitely doesn't include the class keyword. Doubt I'll ever find it useful.


Yeah, like many people, I ended up making my own inheritance routines. Then when class came out, I was half rejoicing, half regretting to put up the work. But well, no thanks. I rather keep using my own far from perfect way of things.


Yes because you can and should promisify old libraries.


No because some async Web API are just a bit more complex than just 'promisify' this or that.


Which ones?


Maybe some codebases mandate it, but it's very common to use either style when it makes the most sense. The classic syntax is by no means deprecated or superseded by async/await.


async/await is excellent syntax when you want things to happen one after another. That's the usual case, and that's what I find myself using 95% of the time.

However, when you want a more fine-grained concurrent execution of different asynchronous things, then() still could be very useful.


Can you give an example of more fine grained control with then?


Often times operations are order-independent. Specifying those as sequential `await`-s does not make a lot of sense in those situations. I guess less fine grained control is desirable under such circumstances :-)

There's also other useful utilities such as Promise.all(), Promise.any() and Promise.race().


const [result1, result3] = await Promise.all([task1(), task2.then(res => task3(res))])


Could that be written

  const task2then3 = async () => task3(await task2());
  const [result1, result3] = await Promise.all([task1(), task2then3()])


I'd just:

    async function getResult3(){
      const res = await task2()
      return task3(res))
    }

    const [result1, result3] = await Promise.all([task1(), 
    getResult3()])


That’s probably good general advice.

One problem. I’m increasingly coming across devs who’ve never used Promises directly, only async/await. They’re introducing all kinds of problems into code because they don’t have that foundational understanding of Promises. I think it’s essential to know how Promises work, even if we generally recommend async/await.

Also, Promise interface can do things that async/await cannot, such as Promise.all, and other unusual async execution scenarios. It’s important to have those tools in your belt.


100%, people should definitely understand Promise.all() and Promise.any().


> Promise interface can do things that async/await cannot, such as Promise.all

PS I should clarify await and Promise.all/any work fine:

    await Promise.all(items)


  (async () => { set(await get()); })();
 
  get().then(r => set(r));
Ignoring error handling I'll often choose the second option.


Much cleaner. You can go even further by using point-free style:

    get().then(set)
It's the try/catch blocks that make async/await truly worse than native promises. I use them sparingly because so often the .then syntax is both clearer and terser.


What don't you like about try/catch? I find the opposite true, the .then/.catch is more confusing.


try/catch introduces new block scopes and interrupt control flow. I find this example very readable, but expanding it into try/catches would make it rather long winded and harder to see the pattern at work as you extend the sequence:

    get()
        .then(handleResult)
        .catch(useFallbackResult)
        .then(updateState)
I prefer concision and functional expressiveness because it reduces the surface area for writing buggy code. Much like how using map instead writing a for loop can eliminate out of range index bugs, chaining promises brings useful guarantees about how the code I do write can be interpreted.


OK. I'll do:

  const result = await get()
  set(result)
But you do you.

Current node and console have top level await BTW.


That only works in an async function. The then example doesn't have that requirement. So the alternative shouldn't either.


Yes, your example isn't complaining about then() being clearer than await (because it isn't) but rather complaining that top level await isn't everywhere yet.

In other words, your complaints have disappeared in node, and will soon in browsers: https://github.com/tc39/proposal-top-level-await

So yes:

    set(await get())


Sometimes you may need to handle a promise in a function that can't be made async.


If a function is inherently sync, then it shouldn't be using promises.


Can you point to anything other than saying "this is obvious"?


No, just experience with a lot of codebases.

Here's a simple question to ask yourself: what if non-IO operations allowed you to use the .then() syntax? If you have the choice to use:

   1 + 1.then(function(result) { ... }
vs

   const result = 1 + 1
Which would you choose?


Using then() doesn't pause execution of the callsite function, while await does. Surely that's a relevant difference here?

It doesn't seem unreasonable to use then() to express: "Run this anonymous function whenever the async thing completes. Meanwhile let's do this other stuff right now."


Both codebases can't do anything until `result` has a value.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: