7 ms·
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'.
by nailer 6y ago
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'.
- jedimastert 6y agoCan you point to anything other than saying "this is obvious"?
- nailer 6y agoNo, 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?
- pavlov 6y agoUsing 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."
- nailer 6y agoBoth codebases can't do anything until `result` has a value.
- ericwood 6y agoMaybe 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.
- deleted 6y ago[deleted]
- golergka 6y agoasync/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.
- postalrat 6y agoCan you give an example of more fine grained control with then?
- golergka 6y agoconst [result1, result3] = await Promise.all([task1(), task2.then(res => task3(res))])
- postalrat 6y agoCould that be written const task2then3 = async () => task3(await task2()); const [result1, result3] = await Promise.all([task1(), task2then3()])
- nailer 6y agoI'd just: async function getResult3(){ const res = await task2() return task3(res)) } const [result1, result3] = await Promise.all([task1(), getResult3()])
- wa1987 6y agoOften 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().
- verisimilidude 6y agoThat’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.
- throw_m239339 6y ago> 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.
- hutzlibu 6y ago"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?
- deleted 6y ago[deleted]
- wa1987 6y agoWell, it's complicated :-) https://stackoverflow.com/questions/36419713/are-es6-classes-just-syntactic-sugar-for-the-prototypal-pattern-in-javascript https://stackoverflow.com/questions/36419713/are-es6-classes...
- postalrat 6y ago(async () => { set(await get()); })(); get().then(r => set(r)); Ignoring error handling I'll often choose the second option.
- Rumudiez 6y agoMuch 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.
- postalrat 6y agoWhat don't you like about try/catch? I find the opposite true, the .then/.catch is more confusing.
- Rumudiez 6y agotry/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.
- nailer 6y agoOK. I'll do: const result = await get() set(result) But you do you. Current node and console have top level await BTW.
- postalrat 6y agoThat only works in an async function. The then example doesn't have that requirement. So the alternative shouldn't either.