Live data from Hacker News

Top-level await in JavaScript is a footgun

gist.github.com

71–80 of 115 posts

Re: Top-level await in JavaScript is a footgun

#71
post #62

Earlier quoted context omitted.

That's false. It wraps each individual module within an async function. They can each proceed concurrently. (And all of them proceed after any `import`ed modules load.)

But any module with a dependency on a module with top-level await will have to wait for that dependency. As will anything depending on that. It's not difficult to imagine some code nested deep in some NPM module completely changing the load behaviour of your app without you knowing.

Yes. Let's rephrase that first sentence.

"Any module with a dependency on data that it needs to execute will have to wait for that data before it executes."

That's a good thing.

Re: Top-level await in JavaScript is a footgun

#72

He posted a follow-up superseding (or extending) the submitted post: > A lot of people misunderstood Top-level await is a footgun, including me. https://gist.github.com/Rich-Harris/41e8ccc755ea232a5e7b88de...

This is probably the bigger deal. It means that not only is top-level await dangerous , it's potentially destructive even when used correctly.

It's also based on yet further misunderstandings (in this case not understanding the ability of engines to do speculative fetches).

Re: Top-level await in JavaScript is a footgun

#73
I agree that top-level await is weird. But the bigger issue is that importing stuff shouldn't be an imperative statement ("load the code at such-and-such address"). That's marrying the language to irrelevant details of how it's parsed and executed. Instead, import should be a static construct that can get special treatment from interpreters and compilers. Header files in C are another instance of the same mistake ("let's make imports work by textual inclusion"). Such tricks can save time in the short run, but a proper module system like Java's is always better in the end.

Re: Top-level await in JavaScript is a footgun

#75

Yes, top-level await sounds silly. It would freeze the entire app... You couldn't even render a loading progress bar - It would defeat the whole point of loading modules asynchronously.

incorrect. `await` is a reserved word only in async contexts, the UI thread event loop still runs while `await`ing.

Re: Top-level await in JavaScript is a footgun

#76

So, this makes me a little sad because the title makes it seem like top-level await is, in general, a bad thing, but upon closer reading, there only seems to be an issue with using await in conjunction with import -- is this a correct assertion, or am I missing something? I've been making heavy use of await lately, and would love if it were available at the top level, but I have zero intention of using it in the way…

No, he provides a simple example of loading a page depending on a sequence of json operations -- code after the first await is stalled until they all finish.

await import just makes problems worse and, probably, almost unavoidable.

Re: Top-level await in JavaScript is a footgun

#77

I agree that top-level await is weird. But the bigger issue is that importing stuff shouldn't be an imperative statement ("load the code at such-and-such address"). That's marrying the language to irrelevant details of how it's parsed and executed. Instead, import should be a static construct that can get special treatment from interpreters and compilers. Header files in C are another instance of the same mistake ("l…

> but a proper module system like Java's is always

Java has a package system not a module system.The difference is important because Java might introduce a module system in the future. And Java isn't built around async programming by default, even loading a jar is synchronous.

Re: Top-level await in JavaScript is a footgun

#78

Another misconception here is the lack of understanding of engines' speculative loading capabilities. It's very easy for an engine to notice `await import('./foo.js')` or even `await fetch('./foo.json')` during the tokenization phase, and realize it might be a good idea to go fetch that file (and in the former case, all of its dependencies). This is already done for HTML's tokenization phase (with img, iframe, etc.),…

But if the engine speculatively loads modules, doesn't that counteract the developer's intention to increase performance by loading a module only when needed?

This is not a problem in HTML loading, because HTML doesn't have `if` statements.

Re: Top-level await in JavaScript is a footgun

#79
post #24

I was never a fan of async/await in C#, I just never found it that useful. I've seen examples of it in JavaScript and the author is always like, "Look at what you normally have to write and now look at what you COULD write with async and await!" And it's like the same goddamn code with a few minor differences. If they axed the whole proposal, I could get through this holiday season without even being depressed a litt…

I find async/await in C# to be super useful, and fairly addictive once you start using it. Say you want to do three independent things in a function. How would you run them in parallel without async? Delegates, background workers, or threads? With async, this is simply done with Task.WhenAll().

What's wrong with threads and synchronizing? async I/O has its own level of complexity. But to be frank a better option is go-routines + channels + select construct like with go. That's really what makes both Go and Erlang unique.

Re: Top-level await in JavaScript is a footgun

#80

Another misconception here is the lack of understanding of engines' speculative loading capabilities. It's very easy for an engine to notice `await import('./foo.js')` or even `await fetch('./foo.json')` during the tokenization phase, and realize it might be a good idea to go fetch that file (and in the former case, all of its dependencies). This is already done for HTML's tokenization phase (with img, iframe, etc.),…

but the use-case for these is not a static import (that is possible already), but a dynamic one, such as:

    await import(`${config.providerType}.js`); 
and this can't be resolved at tokenization phase (and brute-forcing it with speculative/symbolic execution would be too much of a hack IMHO).
Post reply on HN