Dealing with asynchronous code—meaning any kind of code that doesn’t execute immediately—can be tricky. Asynchronous behavior is one of the main sources of complexity in any software environment. It represents a break in execution flow that may lead to any number of outcomes. This article introduces the three ways to handle asynchronous behavior in JavaScript. We’ll start with a look at callbacks, then I’ll introduce promises and the async and await keywords as more modern alternatives.