In this talk we'll discuss 5 alternative approaches to handle async operations: callbacks, events, promises, coroutines and reactive streams. None of them is either legacy or a silver bullet - a good dev needs to pick the right tool for the job. However, in order to understand them, we must step back to fundamentals all these rely on: the mechanics of event loop and run to completion rule, as well as learn to distinguish between sync and async flow. Then we proceed to design patterns built on top of each of the 5 approaches, discussing their strengths and limitations. Funfacts, such as famous Promise.race() included! Come and listen!