JavaScript that is a single-threaded language can be non-blocking with Asynchronous.
A program has to do simple things. It has to allocate memory. It also has to parse and execute function which means read and run commands. Single-threaded means that it has only one call stack. So, it can only do one thing at a time. Call Stack is first in last out. Other languages can have multiple call stacks and these are called multi-threaded. You can also see how that might be beneficial to have multiple call stack. Why was JavaScript designed to be single-threaded? because a multi-threaded environment can have Dead locks. Again, JavaScript is a single-threaded language that can be non-blocking. It has one call stack and it does one thing at a time In order to non-block the single-threaded language,
It should be Asynchronous with call back functions and these callback functions get to run in the background through the callback queue and then the Event Loop to bring it back into the call stack.