JavaScript Event Loop
In the last article, we discussed that JavaScript is a single-threaded language. While this makes the writing of programs easier and avoids the complexity of multithreaded applications. But it comes with some limitations.
While discussing Call Stack earlier we saw that if a function call in a Call Stack takes a huge amount of time to process then the browser can't do anything else and your application UI is no longer responsive. The application is stuck at that point. How to solve this problem? Let's first understand the hosting environment.
JavaScript Hosting Environment
Till ES6, the JavaScript engine has never done anything more than executing a single chunk of your program at any given moment.?
So who tells JavaScript Engine to execute part of your program? JavaScript engine doesn't run in isolation. It runs in the hosting environment.?
The following components come into play when we consider the hosting environment.
Event Loop
The common factor in all the hosting environments is a built-in mechanism called Event Loop. It handles the execution of multiple chunks of your program over time by invoking the JavaScript Engine.
Let's take an example of Ajax call to the server. JS engine makes requests to the server and suspends the execution. It asks the hosting environment to call back using the CallBack function after the operation is complete. The browser then listens for a response from the network and when response is received it puts the CallBack function in the CallBack queue.
How the event loop works??
The event loop monitors Call Stack and Callback Queue. If CallStack is empty then the event loop will take the first event from Callback Queue and push it to Call Stack. Call Stack will run the event. Each iteration is called a tick in the event loop. Each event is a callback function. This indicates that JavaScript Engine is just an on-demand execution environment for any arbitrary JS code.
Let's understand this in detail with the following code.
console.log('Hi')
setTimeout(function callBack() {?
? ? console.log('Callback');
}, 4000);
console.log('Bye');;
When the code is executed below actions will get performed in the hosting environment.
2. console.log('Hi') function execution context is popped out from Call Stack.
领英推荐
3. setTimeout() function is called and its context is placed in the Call Stack. The function is executed. This creates a call to WebAPI due to setTimeout call.
4. Once the execution of setTimeout WebAPI is done it places the callback function in Callback Queue.
5. setTimeout() function execution context is popped out from Call Stack.
6. Function console.log('Bye') is called and its execution context is placed in the Call Stack and the function is executed. It outputs Bye on the screen.
7. console.log('Bye') function execution context is popped out from Call Stack.
8. When Call Stack is empty callBack function is pushed from Callback Queue to the Call Stack by Event Loop.
9. Function callBack() is called and its execution context is placed in the Call Stack and the function is executed. It outputs CallBack on the screen.?
10. The callback function execution context is popped off from Call Stack and again Call Stack is empty.
Interestingly ES6 specifies how the event loop should work so technically it's within the scope of the JS engine's responsibility. One of the main reasons for this is the introduction of promises in ES6 since it requires fine-tuned control over the scheduling operation of the event loop. Later in ES8 JavaScript introduced async/await which makes working with promises easier.?