In JS, code runs single-threaded, that's why asynchronicity is necessary. I cannot use code like result = someRequest(), instead I need to give it a callback someRequest(resultCallback) or write a Promise result = await someRequest().

But why was the language designed like this? Wouldn't it be much simpler if everything was awaited by default? For running functions in parallel (currently e.g. Promise.all(...)), we would then instead be using WebWorkers or Thread.spawn(()=>{...}) the like. But this in my opinion is easily outweighted by being able to write code like this:

const data = [1,2,3].map(v =>



My point being, whether sleep(1000) actually suspends the entire thread or whether it is non-blocking, is internal logic and most cases irrelevant to the programmer. Contrary to for example Rust, where you always need to actively decide for or against spawning an extra thread. Why do we need to bother with the special syntax then?

In case I am not missing anything, why is there no common JS preprocessor for this? It would need to prefix everything with await and rewrite (besides others) all Array processing functions like .map().


  • 3
    JavaScript wasn't really designed, it was quickly thrown together in a two week effort by a single person in order to add another bullet point for a marketing slide. Everything since then is trying to bring as much modern goodness to the language while still staying backwards-compatible. The old APIs like setInterval or the XMLHttpRequest are therefore callback-based.
    – amon
    Apr 4, 2021 at 17:44
  • "whether sleep(1000) actually suspends the entire thread or whether it is non-blocking, is [...] in most cases irrelevant to the programmer" - so, you're saying it doesn't matter to you whether sleep(1000) waits for 1000 ms or returns immediately, as if it's a no-op? Apr 4, 2021 at 18:23
  • @FilipMilovanović No, I didn't mean it like that. In either case it does indeed wait for 1000ms, but in a hypothetical await-less JS, the thread can do other things in the meantime. It would be non-blocking, but without the need for an await.
    – phil294
    Apr 4, 2021 at 18:50
  • Thanks @amon, I marked this question a duplicate, it is exactly what I am asking, too. Not sure about the downvotes here though.
    – phil294
    Apr 7, 2021 at 13:39

1 Answer 1


But why was the language designed like this?

Because JavaScript is just the tiny little bit of glue code which sits between your browser and your proper code which runs in a Java applet. There's no need for it to have anything like asynchronous code, because everything it does completes in a fraction of a second.

Now, history didn't work out that way but you if you're asking "why was the language designed like this" you can't ignore what the original purpose of the language was.

  • LiveScript was released from the beginning both in the browser as a client-side scripting language and as part of Netscape's server-side web framework as a server-side application language. It is quite ironic that LiveScript was a server-side application language from the get-go, whereas Java was a client-side scripting language for a long time. Apr 4, 2021 at 17:45
  • To add to the historical perspective: most mainstream languages got async features and libraries not that long ago. Apr 4, 2021 at 17:47

Not the answer you're looking for? Browse other questions tagged or ask your own question.