An important concept in this context is an Event Loop. It goes on and on, each iteration of it being called a “tick”. If during such a tick events wait in a queue, they are going to be executed one by one. A good example is the popular setTimeout function. Its first argument is a callback – a function that is executed after a certain amount of time. When the setTimeout function is being interpreted, it is pushed to the top of the call stack. It sets up a timer, and when it goes off, it throws your callback to the end of the event loop – that means it is not going to be executed precisely after the amount of time specified – other actions waiting in the queue need to be dealt with first. When the time comes, your callback is pushed to the call stack to be executed. Same goes for your request sent to the server – when you receive a response, a function that you want to execute afterwards is thrown to the end of the queue.
Call stack is a data structure under the hood – it records where we are in the program. Stepping into a function, we put it on top, returning from it would mean popping it off the stack. Let’s demonstrate a bit with some recursion: