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