What is the difference between synchronous and asynchronous code?
Synchronous code runs one statement after another, and each waits for the previous to finish. Asynchronous code starts an operation and continues without waiting, handling the result when it arrives.
The distinction matters because some operations are slow for reasons unrelated to your program: reading a file, querying a database, calling another service. During that wait the processor has nothing to do. Synchronous code sits idle; asynchronous code does something else.
A useful clarification is that asynchronous does not mean parallel. In a single-threaded runtime nothing runs simultaneously. The thread interleaves work, running other code during waits. Two asynchronous requests started together overlap in time because the waiting overlaps, not because two things execute at once.
The practical consequence is that anything genuinely computational blocks regardless of how it is written. Marking a function asynchronous does not make a long loop inside it yield to anything else. This is the most common misunderstanding, and it produces the surprising result that an asynchronous server becomes unresponsive during a heavy calculation.
The mechanisms for handling results have evolved through callbacks, then promises, then syntax that lets asynchronous code read sequentially. The last is now standard and is worth using consistently, because it makes error handling work with ordinary try and catch rather than requiring a separate path.
The cost of asynchrony is that ordering becomes explicit. Code after an unwaited call runs before the result exists, which is the source of a large share of bugs where a value is undefined for no apparent reason. Being deliberate about what is awaited, and what is intentionally started and left running, is most of what writing correct asynchronous code involves.