7 ms·
It's nice, I guess, but huge? Instead of: async function main() { // code } main().catch(console.error); I'll be maybe writing: try {
by megous 7y ago
It's nice, I guess, but huge?
Instead of:
async function main() {
// code
}
main().catch(console.error);
I'll be maybe writing:
try {
// code
} catch (ex) {
console.error(ex);
}
Hrm?
- casret 7y agoOne thing that has bitten me is when you are using vm.run* and friends, it's impossible to get a result of it if you need to use async calls. Hopefully this solves that case. There is also the original use case that the original proposal of needing to do async calls when during module loading.
- mattwad 7y agoI think the boon here will be for scripts that run once. Say I just want to query a few tables. Now, I no longer need a `main()` wrapper: const result = await db.events.find(); console.log(result); That's my whole script
- james-mcelwain 7y agoOr my preferred (gross) version: void async function main() { // code }()
- elyobo 7y agoMine all tend to look like (async () => { // code })().catch(console.error)
- jraph 7y agoWow, I had completely forgotten the existence of void in JavaScript. Why is it needed here? To force an expression without using the parentheses? Edit: Yes, it seems so, and this usage with functions is explicitly documented there: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/void https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...
- ericlewis 7y agoYep. Exactly why. Seems silly since it doesn’t really care for types in the first place.
- deleted 7y ago[deleted]
- TimTheTinker 7y agoFor some use cases, the difference can be a little more dramatic. fetch(allResourcesUrl).then(async response => { let allResources = await response.json(); let pageResource = await (await fetch(allResources.page1.url)).json(); // set up page with pageResource }); can be replaced with { let allResources = await (await fetch(allResourcesUrl)).json()); let pageResource = await (await fetch(allResources.page1.url)).json(); //set up page with pageResource } Note use of a top-level block instead of a function context to hide local variables.
- elyobo 7y agoWhat's with the `let` though?
- joshAg 7y agolet plus the curly bracket scoping means that the variables only exist within the curly brackets, and not the global state.
- aledalgrande 7y agoMaybe he meant why not const?
- spartanatreyu 7y agoYou would use const, unless you wanted to reassign the variable later in the same scope.
- earthboundkid 7y agoConst is a complete waste of time for non-primitive types. I defy anyone to show me a single bug in a popular program that could have been prevented by using const for a function local object. It can’t be done. There are bugs caused by mutatable state. There are bugs caused by reassigning globals. There has never been a bug caused by reassigning a function local variable while leaving it mutable.
- nailer 7y agoYou forgot the IIFE
- Scooty 7y agoTop level await does more than remove a main function. If you import modules that use top level await, they will be resolved before the imports finish. To me this is most important in node where it's not uncommon to do async operations during initialization. Currently you either have to export a promise or an async function.
- stagas 7y agoOh that's interesting if this is the case. So now a module export can contain an asynchronously initialized db handler for example?
- spankalee 7y agoPlease don't do that though!
- tiglionabbit 7y agoDo we really want slow imports though? If you have a bunch of modules with async setup functions, would you not be able to Promise.all() them?
- pandapower2 7y agoSure, in many situations, but I guess if you need to setup things have have dependencies (init A then init B then init C) this will help.
- dvlsg 7y agoHow so? I'm not seeing the benefit over exporting A, B, and C as functions, and then putting them together in another spot (like a composite root for pure DI, or an IoC container, etc). Is the argument for top-level await that you don't need the other spot? Because I feel like you still do - except now it's implicitly inside not only A, but likely B and C as well to some extent. And in a very inflexible way.
- Rapzid 7y ago
- Zarel 7y agoIf all you're doing on catch is forwarding to `console.error`, you could just write: // code Outputting errors to console is the default behavior.
- olalonde 7y agoThere's an important difference: the process will crash if you don't catch the error.
- robert_tweed 7y agoWhile this is 100% correct, if the main function has returned then the process was going to end anyway (assuming there isn't additional code after the call to main). If there's a main loop, then the catch needs to be inside that loop, not outside of main. The only difference it will make here is to suppress the default stack trace[1] and errorlevel returned to the shell. If you are writing in this kind of "scripting" style, you probably don't want to suppress errorlevels, so leaving out the catch is not only simpler, it is safer. [1] You may get a stack trace with an Error object, but not the default one from the Node process.
- olalonde 7y ago> While this is 100% correct, if the main function has returned then the process was going to end anyway (assuming there isn't additional code after the call to main). That's not necessarily the case (or maybe poorly worded), e.g.: async function main() { // code setInterval(() => console.log('hey'), 1000) } main() In real life, it would probably be a HTTP server holding up the process. It's true that you likely want to crash hard if you have unhandled error during server initialization but I would still catch the error because Node.js will otherwise print a bunch of ugly "UnhandledPromiseRejectionWarning" messages. E.g.: main().catch(err => { console.error(err); process.exit(1); }); With top level async landing in v8, I guess Node.js will eventually stop printing those warning messages.
- 7y ago