A brief look at async-await
21–30 of 47 posts
Re: A brief look at async-await
#22Earlier quoted context omitted.
>Your "legible" example is only legible because you are not doing anything actually important like error handling and logging. async function doStuff() { try { // Fetch things concurrently const [ foos, bars, bazs, ] = await Promise.all([ getFoos().then((res) => { console.log(`getFoos done with ${res}` return res })), getBars(), getBazs() .catch((err) => { // handle only the error in getBazs }), ]); // Do stuff with…
I was about to write up that exact example of the nested handlers.
As always, who you are working with matters a LOT, and if I were on a team where a good portion of the devs weren't comfortable with that style of code, then I'd use more verbose ways of doing it that are more inline with what they are expecting.
But on the rare occasion that the complexity necessitates the advanced promise stuff, or in jobs (like my current one) where all of us devs are super comfortable with promises being used like this, then it's a dream to work with them!
Re: A brief look at async-await
#23Earlier quoted context omitted.
(see below)
But those 2 examples aren't doing the same thing. My Promise.all example will fire off the getFoos, getBars, and getBazs requests all at the same time, and then do things at different moments with the results in some cases. Yours will do them serially like this: getFoos -> wait for it to resolve -> run getBars -> wait for it to resolve -> run getBazs -> wait for it to resolve -> run doStuff And if individually handle…
I would do it like this (if I didn't have access to "async/await" which is sadly the case for me in Node sometimes):
function doStuff (foos, bars, bazs, callback) {
// do stuff
}
function getStuff (callback) {
let foos, bars, bazs;
let semaphore = 3;
function collector () {
if (--semaphore) {
return;
}
doStuff(foo, bars, bazs, callback);
}
getFoos((err, res) => {
if (err) {
return callback(err);
}
foos = res;
collector();
});
getBars((err, res) => {
if (err) {
return callback(err);
}
bars = res;
collector();
});
getBazs((err, res) => {
if (err) {
return callback(err);
}
bazs = res;
collector();
});
}
It is more lines of code but is boringly simple to read and allows for fully custom error handling (an example of the semaphore + collector pattern I mentioned below in another comment).The custom error handling would be in the individual "get" functions which allows for easier testing.
The semaphore in the collector is the most tricky part and I would possibly replace it here with an "if" to check that all the variables have a value - depends on what sort of data I could get back.
Re: A brief look at async-await
#24Earlier quoted context omitted.
But those 2 examples aren't doing the same thing. My Promise.all example will fire off the getFoos, getBars, and getBazs requests all at the same time, and then do things at different moments with the results in some cases. Yours will do them serially like this: getFoos -> wait for it to resolve -> run getBars -> wait for it to resolve -> run getBazs -> wait for it to resolve -> run doStuff And if individually handle…
You are right - got mixed up in the responses - serves me right for trying to do too many things async! I would do it like this (if I didn't have access to "async/await" which is sadly the case for me in Node sometimes): function doStuff (foos, bars, bazs, callback) { // do stuff } function getStuff (callback) { let foos, bars, bazs; let semaphore = 3; function collector () { if (--semaphore) { return; } doStuff(foo,…
Promises are nice because they have a single purpose, to resolve or reject a promised value. So when I see them, I can pretty much instantly understand what it's doing. `Promise.all` tells me that it's waiting for all of them to resolve at once, `Promise.race` tells me that the result will be the first of them to resolve or reject.
With callbacks, everything is "custom". So looking at your example I'd need to fully read the function to get an understanding of what it's doing, vs just knowing that Promise.all means "wait for them all and then resolve".
Granted, if where you are working tends to avoid promises or heavily uses a language like golang where your style is much more common, then I actually completely agree with you that the callback version is going to be more maintainable, readable, and easier to work with in your team.
But if/when your org/team collectively learns the "shorthand" that promises can provide, IMO they become much simpler to read and understand in most cases. It's basically a way of providing structure to really common patterns like yours, so that the actual structure fades into the background and the important stuff (what you are trying to do) becomes the only focus.
In other words it's syntactic sugar. With all the benefits and drawbacks that any syntactic sugar provides.
Re: A brief look at async-await
#25I'll admit the only reason I've noticed the domain is my corporate IT seems to have all sites on weird TLDs blocked by default :/
Re: A brief look at async-await
#26I know its kind of meta, but what's with all the blog posts lately hosted on a *.christmas domain? These posts seem to have nothing to do with the holiday I'll admit the only reason I've noticed the domain is my corporate IT seems to have all sites on weird TLDs blocked by default :/
Re: A brief look at async-await
#27I know its kind of meta, but what's with all the blog posts lately hosted on a *.christmas domain? These posts seem to have nothing to do with the holiday I'll admit the only reason I've noticed the domain is my corporate IT seems to have all sites on weird TLDs blocked by default :/
Re: A brief look at async-await
#28Earlier quoted context omitted.
You are right - got mixed up in the responses - serves me right for trying to do too many things async! I would do it like this (if I didn't have access to "async/await" which is sadly the case for me in Node sometimes): function doStuff (foos, bars, bazs, callback) { // do stuff } function getStuff (callback) { let foos, bars, bazs; let semaphore = 3; function collector () { if (--semaphore) { return; } doStuff(foo,…
well IMO that is much more difficult to read for me. Promises are nice because they have a single purpose, to resolve or reject a promised value. So when I see them, I can pretty much instantly understand what it's doing. `Promise.all` tells me that it's waiting for all of them to resolve at once, `Promise.race` tells me that the result will be the first of them to resolve or reject. With callbacks, everything is "cu…
The little bit of magic that makes your code sane is the "await" in front of "Promise.all()" and makes it more elegant than the callback version.
Re: A brief look at async-await
#29I know its kind of meta, but what's with all the blog posts lately hosted on a *.christmas domain? These posts seem to have nothing to do with the holiday I'll admit the only reason I've noticed the domain is my corporate IT seems to have all sites on weird TLDs blocked by default :/
Apparently it's supposed to be some kind of advent calendar type thing, 25 posts in 25 days. Which explains the christmas tld.