Remix.run Logo
skybrian 2 days ago

Ultimately, it's because of how JavaScript models time.

In a browser, JavaScript has a single event queue, and events are delivered one at a time. Event delivery is supposed to be fast. Conceptually, handling one event can be seen as a single tick of a clock, and practically, it should be less than one animation frame, so the UI doesn't freeze. If something takes time, you need to split it up over multiple events, so that it spans multiple clock ticks.

An async function call is one that can return in a different clock tick. A "normal" JavaScript function call always returns in the same clock tick, and if it takes too long, it makes the clock tick take longer, holding everything up until it's done.

This is a logical consequence of JavaScript starting out single-threaded and being used to write UI event handlers. In other languages, there isn't this distinction. Assumptions about event handling aren't baked so deeply into the language, so normal function calls in other languages don't make this guarantee about happening atomically.