-
Javascript runtime environment is the big picture for a javascript program execution, runtime environment is where your javascript code will be executed by utilizing a set of components together.
-
Javascript runtime environment is the reason why we can write asynchronous code given that javascript is single threaded and synchronous, runtime environment will provide us with apis to be able to write asynchronous code.
- Javascript Engine
- Environment Apis, Examples: [Browser Web Apis, Node Server Apis, ... etc]
- Task Queue
- Event Table
- Event Loop
Javascript runtime environment is responsible for providing apis to interact with the host application
-
Examples:
- Browser runtime environment will provide us with Wep Apis like
DOM,XMLHttpRequest,setTimeout,setInterval... etc - Node runtime environment will provide us with
FileSystem,http... etc
- Browser runtime environment will provide us with Wep Apis like
Task Queue, Event Table and Event loop are the three components that give us asynchronous capability in javascript.
-
Whenever javascript engine finds a method from runtime environment asynchronous api like
setTimeout, it will pop it from execution stack and send it toEvent Tableinside runtime environment, this way execution of synchronous code will not be blocked, and javascript engine will be able to execute next execution context in execution call stack -
setTimeoutwill stay inEvent Tableuntil specified delay is finished and then it will be sent toTask Queue. -
Event Loopwill keep checking bothExecution Call Stackin engine andTask Queue, and whenever there is a queued task inTask Queueit will push it toExecution Call Stackif it is empty. -
It is very important to understand that
Event loopcannot push any task toExecution Call Stackuntil it is empty.
1 console.log('start');
2 const startTime = new Date();
3 setTimeout(function myCallbackFunction() {
4 const endTime = new Date();
5 const timeDiff = endTime.getTime() - startTime.getTime();
6 console.log(`${timeDiff / 1000} seconds`);
7 console.log('setTimeout callback is executed');
8 }, 1000);
9 console.log('end');
// start
// end
// 1.001 seconds
// setTimeout callback is executedNow lets see how runtime environment components will work together for the above asynchronous code snippet:
- Line 1: Engine will push
console.log('start')to execution call stack and then will pop it once finished - Line 2: Engine will push
new Date()to execution call stack and then will pop it once finished - Line 3: Engine will push
setTimeoutto execution call stack and then will realize that it is a runtime asynchronous api, so it will pop it and send it to runtime environment that will insert it inEvent Table - Line 9: Engine will push
console.log('end')to execution call stack and then will pop it once finished - Now engin's execution call stack is empty and nothing is happening
- 1 second passed since we called Line 3, so runtime environment will remove
setTimeoutfromEvent Tableand queuemyCallbackFunctiontask insideTask Queue Event Loopwill check if any task is there inTask Queueand will push that task to execution call stack only if it is empty, so it will be pushed immediately.- Now
myCallbackFunction()is in execution call stack - Line 4: Engine will push
new Date()to execution call stack and then will pop it once finished - Line 5: Engine will push
startTime.getTime()and pop it then pushendTime.getTime()and pop it - Line 6: Engine will push
console.log(${timeDiff / 1000} seconds);and pop it - Line 6: Engine will push
console.log('setTimeout callback is executed');and pop it
console.log('start');
const startTime = new Date();
setTimeout(function myCallbackFunction() {
const endTime = new Date();
const timeDiff = endTime.getTime() - startTime.getTime();
console.log(`${timeDiff / 1000} seconds passed`);
console.log('setTimeout callback is executed');
}, 1000);
let i = 0;
while(true) {
if(i >= 10000000000) {
break;
}
i++;
}
console.log('end');
// start
// end
// 12.058 seconds passed!
// setTimeout callback is executedNotice how in Example 18.1 myCallbackFunction is delayed 12 seconds not 1 second as we passed in setTimeout this is because myCallbackFunction was in Task Queue but Event Loop was not able to push it in Execution Call stack, because it was not empty.
From this we can understand that the value we pass to setTimeout is the minimum delay to the callback function not the exact one.