Live data from Hacker News

Top-level await in JavaScript is a footgun

gist.github.com

31–40 of 115 posts

Re: Top-level await in JavaScript is a footgun

#31
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…

The async/await example is much cleaner. I also think it's a great pattern for async code. It allows you to get away from callbacks altogether, and replaces those annoying conventions with "synchronous-like" code, which to me as someone who writes async code daily, is a god-send.

The amount of visual noise in the promise example cannot be understated.

Re: Top-level await in JavaScript is a footgun

#32
post #12

Earlier quoted context omitted.

ES6 modules are declarative in the sense that the dependencies are statically analyzable.

> If anything, top level async would be an improvement, as it would give developers no reason to do synchronous IO. Top-level async would make asynchronous IO no different from synchronous IO! It's the worst of both worlds. > the dependencies are statically analyzable Exactly – which means modules can be loaded concurrently, without having to execute the code. By contrast, imperative loading has to happen sequentiall…

> Top-level async would make asynchronous IO no different from synchronous IO! It's the worst of both worlds.

No it's not. Synchronous IO blocks everything. Asynchronous IO with top level await would still allow things queued in the event loop to execute. Plus, top level await + Promise.all would allow you to do operations concurrently, something that synchronous doesn't.

Re: Top-level await in JavaScript is a footgun

#33
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 it's described in the article?

Re: Top-level await in JavaScript is a footgun

#34
post #10

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

I'm only using normal callbacks and async javascript iterators . No promises or await.

Easier mental model, no surprises, still easy to organize.

Re: Top-level await in JavaScript is a footgun

#35
post #12

I know that the argument that "silly developers shouldn't be allowed to do silly things" is a valid one, but I don't see a convincing argument that top level await is worse than what developers are currently doing, which is use synchronous functions to do IO at the top level. If anything, top level async would be an improvement, as it would give developers no reason to do synchronous IO. Edit: Additionally, ES6 modul…

ES6 modules are declarative in the sense that the dependencies are statically analyzable.

True, but I interpreted the OP as criticising any execution of code on module load (other than declaring exports).

Unless loading a file is a bottleneck, which I doubt.

Re: Top-level await in JavaScript is a footgun

#36

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 are localised and much easier to predict/reason about.

Re: Top-level await in JavaScript is a footgun

#37
post #22

I'm not terribly familiar with this new proposal but I have used the regular async/await features quite extensively and can't really see a problem here. Since async/await deal with promises, there's nothing stopping anyone from not awaiting a dependency at the top level so that some loading logic can be run. In addition, since these are promises, there's nothing stopping us from awaiting multiple promises at once in…

Agree that `await` by itself is useful, and your example shows the correct way to use it for concurrent activity. 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.

> 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?

Re: Top-level await in JavaScript is a footgun

#38
post #22

I'm not terribly familiar with this new proposal but I have used the regular async/await features quite extensively and can't really see a problem here. Since async/await deal with promises, there's nothing stopping anyone from not awaiting a dependency at the top level so that some loading logic can be run. In addition, since these are promises, there's nothing stopping us from awaiting multiple promises at once in…

Agree that `await` by itself is useful, and your example shows the correct way to use it for concurrent activity. 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.

It seems it would only cascade through the entire app if only the app was designed around dependencies being available first before other code is run. That is, if the app is designed badly.

Again, I don't understand the point of the proposal in this context since nobody should be awaiting a long list of dependencies to load first. If you have 100 dependencies that means you have 100 HTTP requests, which is really a poor design decision. That's why we bundle up dependencies into fewer chunks first before sending them down to the client.

Edit: I understand that this would become a sequential issue if one import leads to a request which leads to further imports which lead to more subsequent requests. My point is that unless the developer(s) really don't understand how async/await works, they wouldn't reasonably design an app like this.

Re: Top-level await in JavaScript is a footgun

#39
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().

Re: Top-level await in JavaScript is a footgun

#40

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…

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 :/.
Post reply on HN