Так вы сами почти и ответили. Язык однопоточный, поэтому каждая операция ждет завершения предыдущей при синхронном программировании. И не ждет - при асинхронном. А чтобы определить завершение асинхронной операции были придуманы Промисы и асинки.
Это я, конечно, на пальцах. Академические ответы про асинхронность легко нагуглить.