Dealing with asynchronous computation in JavaScript is a hard task, and this is because all your code runs in a single thread. So, to keep this thread available most operators dealing with I/O use a callback to return the control to your program when the data is available.
The concept of threads and how JavaScript virtual machines work internally goes beyond the scope of this book, and it is not necessary to understand it.
The extensive use of callback functions usually leads to a problem called callback hell, which is basically a code with too many callbacks making it really hard to read from a programmer perspective. To mitigate this problem, promises are now part of the standard JavaScript and are implemented by all modern browsers. As promises are composable by nature, it makes your code cleaner and gives you a safe way out from callback hell.
But promises have only basic constructs...