Live data from Hacker News

V8 adds support for top-level await

chromium.googlesource.com

181–190 of 310 posts

Re: V8 adds support for top-level await

#181
post #79

Earlier quoted context omitted.

Seems like you should be able to build a lock mechanism fairly simply with async/await, but I agree, it would be nice if it was a built in primitive. It does feel a little silly to implement a lock function when the engine much be using one to support its async functionality in the first place, so you're introducing a lot of inefficiency.

I don't think it's true that the engine must be using a mutex to support it's async functionality. Or that it is true that an OS mutex will be any more efficient than alternative solutions. A mutex really can only exist to serialize async code. If you want it serialized that likely means that code shouldn't be async in the first place.

You're right that it may not be required for the async functionality (especially since lock-free schedulers exist, and the engine is basically a single processor scheduler for processes). I do think it's likely in use other places though, just because it's much easier to write correct code with one.

Re: V8 adds support for top-level await

#182

Earlier quoted context omitted.

Javascript devs, for all their flaws, understand async programming far, far better than the average C programmer. Indeed, your assertion that we need "locking primitives" to counteract "race conditions" is evidence of that. Yes, JavaScript can have race conditions, but not multi-threaded race conditions that cause resource contention [0]. So what good would locking primitives be? And as a solution to single-threaded…

Here's an example of how you might get a race condition in JS: async function deduct(amt) { var balance = await getBalance(); if (balance >= amt) return await setBalance(balance - amt); } One way to resolve this would be with a mutex to protect the balance during the critical section (which is async). What would you suggest instead?

Can anyone explain this to me, how is it a race condition?

Re: V8 adds support for top-level await

#183

Earlier quoted context omitted.

Because all the promises are waiting on `fileSize`, right? But do you mean that JS 1. will read `totalSize` then 2. do the asynchronous call, then 3. add and set? Seems like it's ambiguous and JS could just as easily read `totalSize` after the call, and all would be OK. Or is the ordering specified? Thanks for this clever example!

The ordering is specified left to right. totalSize += await getSize() becomes totalSize = totalSize + await getSize() So all the map callbacks run one by one, read totalSize as 0, and then suspend waiting for getSize(). Each one then resolves and assigns totalSize to be 0 + the size. The race is what order the getSize() calls return in since only the last one will control the return value. Otherwise the issue isn't a…

Wow, why would you define it this way. I had to check the spec because I didn't believe you. They got #2/#3 backwards.

https://es5.github.io/#x11.13.2

Re: V8 adds support for top-level await

#184
post #137
post #9

Earlier quoted context omitted.

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?

If all you're doing on catch is forwarding to `console.error`, you could just write: // code Outputting errors to console is the default behavior.

There's an important difference: the process will crash if you don't catch the error.

Re: V8 adds support for top-level await

#185
post #103
post #81

Earlier quoted context omitted.

> when you use async/await instead of promises or callbacks, things do change because two sequential lines of code are no longer two truly sequential instructions I thought async/await was just syntactic sugar for promises?

No it's not. async/await's semantic is similar to coroutines, and is implemented by them.

Maybe provide some evidence of this, I've also understood them as syntactic sugar for Promises.

Although I have found that babel does seem to transpile them differently to Promises

Re: V8 adds support for top-level await

#186

Earlier quoted context omitted.

Maybe he meant why not const?

Const 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.

[deleted]

Re: V8 adds support for top-level await

#187
post #170

Earlier quoted context omitted.

So use a Promise like a lock then. If it exists, wait on it. If not create one… Of course you don’t need to use the existence of a Promise as your Boolean in this case. You can simply use the Boolean state in addition to the Promise because your code is not going to yield while atomically setting one Boolean variable.

That would unblock all coroutines waiting for the promise, instead of just the first one. It's not that trivial, that's the point.

You moved the goal posts on me. But the solution for your next scenario is actually pretty trivial though isn’t it?

You don’t really need what you call locking in a single-threaded world. You just need a state machine.

Re: V8 adds support for top-level await

#188
post #70

Earlier quoted context omitted.

One use case I often find is a caching layer between JS and a HTTP call. If there are 2 calls to a non cached endpoint, the HTTP will fire off twice before caching the result. You can work around this by returning the first promise from the cache, but this is essentially a mutex. Having locking primitives would solve this and require less boilerplate code.

You write this boilerplate to avoid one extra non-cached HTTP call on a (browser?) client? Am I understanding correctly?

[deleted]

Re: V8 adds support for top-level await

#189
post #66

Earlier quoted context omitted.

Promises are nice in JavaScript because they’re just a value with no magic. Anything can create them, not just async functions. Generic/higher-order functions and so on can get involved without needing to know the difference. A proposal to introduce magic at calls sounds really awful, sorry.

No magic is rich — they swallow errors, for one. In any case, I don't think anything I said precludes the creation of promises outside of async functions, in fact quite the opposite. The difference is that the runtime would implicitly await the resolution of a promise returned from a function (any function, there'd be no such thing as an "async function") and if you actually wanted things to progress asyncronously yo…

> and the only way to know if you need await is to peruse docs (hoping that they're accurate) or judiciously sprinkle it everywhere.

Knowing whether what you’re calling is async is part of knowing what you’re calling at all. Sprinkling await everywhere to try to mask the difference is horrifying. (I kind of wish it didn’t work on non-thenables for that reason – half the time, it’s a bug.)

Re: V8 adds support for top-level await

#190
post #83

Earlier quoted context omitted.

Top 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.

No one should be asynchronously executing code on import? I'd rather my code call a function to kick it off.

Please, this.

Synchronous effectful imports are already are the source of so much frustration, and now we're adding asynchronicity to it?

Just export a init function and let your users choose when/where to run your effectful initialization code, sync or async.

Post reply on HN