Live data from Hacker News

Top-level await in JavaScript is a footgun

gist.github.com

61–70 of 115 posts

Re: Top-level await in JavaScript is a footgun

#61

Earlier quoted context omitted.

The comparison to sync XHR is apt – put it this way, if you could go back in time and prevent synchronous XHR from being a thing, wouldn't you?

Yep, I probably would. However, the argument against allowing await in top level code doesn't make much sense if all of these bad side effects already exist.

This would just increase the surface area of a bad side effect, though. Barely anyone uses sync XHR and the API is being phased out to the Fetch API - why would we encourage re-adding baggage like that?

Re: Top-level await in JavaScript is a footgun

#62

Earlier quoted context omitted.

An async function is non-blocking. await is blocking within the async function . Top-level await basically boils down to a proposal to wrap your entire app inside an async function.

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.

Re: Top-level await in JavaScript is a footgun

#63

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…

Whether or not it's a module or something else being awaited isn't the problem. The issue that if your app.js (or whatever) has dependencies on modules with top-level awaits, however far removed, it can't execute until they're done. In other words top-level await essentially blocks your entire app. Using await inside an explicitly async function is great, because it only blocks code inside that function – the effects…

Now we just need asynchronous imports and all is well again.

I can't even tell whether I'm being sarcastic or not.

Re: Top-level await in JavaScript is a footgun

#64
post #60

Slighty off-topic, I'm surprised/amazed that top-level await is permitted at all. This looks like it would allow some interesting new patterns in web programming, though at the expense of wreaking havoc with traditional execution models. For example, await in event handlers: Is the event object still valid when doAnotherThing is called? Or await in script blocks: Welcome back, document.write(await fetchUsername()); L…

top level await is only possible in grammar w/ `await` as a reserved word. This is limited to Modules (type=module) and async functions. You can't put it in your click handler or random Script like the examples you gave.

Re: Top-level await in JavaScript is a footgun

#65
post #11
post #10

Am I the only one who is happy using normal callbacks? I think they are the best representation of the asynchronous flow.

Well, I was happy using normal callbacks, but then promises made me a bit happier and now I even happier with async/await. You can definitely write clean code with only callbacks, but one has to be pretty careful if there are many nested asynchronous actions. Promises and await make that code very much clearer.

And then as you use promise based code more and more (including with async/await), you eventually come to realize that while it looked good at first, its deeply, deeply flawed, and is at best a stepping stone to Observables :)

Re: Top-level await in JavaScript is a footgun

#66
post #3

Earlier quoted context omitted.

It's not so much about blocking as it is about delaying the module waterfall. E.g. a module that did `await new Promise(_ => setTimeout(_, 5000))` at the top would prevent any of its dependents from being loaded for 5 seconds.

That's false. Module loading and execution are separate stages. The dependent modules would load before this await is ever reached.

Sounds like I misunderstood. Thanks for the correction!

Re: Top-level await in JavaScript is a footgun

#67

Earlier quoted context omitted.

Ah, thank you, that makes sense. The term "footgun" is pretty interesting here, as it generally refers to something that allows one to shoot one's self in the foot. In this case, it's allows someone else to shoot you in the foot by hiding it in their code :/.

On the subject of whether or not this is really a problem because people can just be educated not to do this, the author said: > You'll educate some of them, but not all. If you give people tools like with, eval, and top-level await, they will be misused, with bad consequences for users of the web. This is still a footgun, because it makes it easy for people to introduce wide ranging and sometimes subtle bugs in thei…

And as we all know, what JS is missing is a new way for unknowing devs to build slow and buggy products.

Re: Top-level await in JavaScript is a footgun

#69

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.

Re: Top-level await in JavaScript is a footgun

#70

Earlier quoted context omitted.

> The problem with top-level await is that any modules depending on a module with a TLA cannot execute until it's done – the effects cascade and magnify throughout your app, rather than being confined to an explicitly async function. Can't I already do this by putting a fs.readFileSync call or a synchronous AJAX call in my code?

The comparison to sync XHR is apt – put it this way, if you could go back in time and prevent synchronous XHR from being a thing, wouldn't you?

See elsewhere in this thread for why the comparison to sync XHR is very misleading.
Post reply on HN