Event loop
/** | |
* Event loop. | |
* | |
* Read details here: | |
* http://dmitrysoshnikov.com/ecmascript/javascript-the-core-2nd-edition/#job | |
* | |
* by Dmitry Soshnikov <dmitry.soshnikov@gmail.com> | |
*/ | |
/** | |
* Call-stack. | |
*/ | |
const stack = []; | |
/** | |
* Jobs queue. | |
*/ | |
const jobs = []; | |
/** | |
* Event loop spins, and checks whether something was enqueued. | |
* If the execution stack is empty, it picks a job, and executes it. | |
* A job can enqueue other jobs. | |
*/ | |
setInterval(function eventLoop() { | |
console.log( | |
`\n Analyzing jobs queue:`, | |
`[${jobs.map(job => job.name).join(', ')}]\n` | |
); | |
// Something is on the stack, can't run jobs yet. | |
if (stack.length) { | |
return; | |
} | |
// Nothing to run. | |
if (!jobs.length) { | |
return; | |
} | |
// Pick up the next job, and put it onto the stack. | |
const job = jobs.shift(); | |
run(job); | |
}, /* Spin! */ 1000); | |
/** | |
* Executes the code. | |
*/ | |
function run(activation) { | |
// Emulate stack "push-pop". | |
stack.push(activation); | |
console.log( | |
`Running "${activation.name}", stack:`, | |
`[${stack.map(context => context.name).join(', ')}]` | |
); | |
// Run the code. | |
activation(); | |
stack.pop(activation); | |
} | |
/** | |
* The `postponeCall` waits for the ms, and then | |
* enqueues the activation as a job. | |
*/ | |
function postponeCall(runnable, ms) { | |
setTimeout(() => jobs.push(runnable), ms); | |
} | |
// ----------------------------------------------------------------------------- | |
// Tests. | |
function one() { | |
run(two); | |
} | |
function two() { | |
postponeCall(three, 10); | |
} | |
function three() { | |
postponeCall(four, 10); | |
postponeCall(five, 20); | |
run(six); | |
} | |
function four() { | |
return; | |
} | |
function five() { | |
return; | |
} | |
function six() { | |
return; | |
} | |
// Go! | |
(function start() { | |
// Enqueue the first call, which will run other functions, | |
// and enqueue other postponed calls. | |
postponeCall(one, 100); | |
})(); | |
// ----------------------------------------------------------------------------- | |
// Results: | |
/* | |
Analyzing jobs queue: [one] | |
Running "one", stack: [one] | |
Running "two", stack: [one, two] | |
Analyzing jobs queue: [three] | |
Running "three", stack: [three] | |
Running "six", stack: [three, six] | |
Analyzing jobs queue: [four, five] | |
Running "four", stack: [four] | |
Analyzing jobs queue: [five] | |
Running "five", stack: [five] | |
Analyzing jobs queue: [] | |
Analyzing jobs queue: [] | |
Analyzing jobs queue: [] | |
... | |
*/ |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Good example. But I am confused "CallStack" between Event Loop and JS Engine. I thought "CallStack" is part of the JS engine, but it is in Event Loop in this example. Are they same things? |
This comment has been minimized.
This comment has been minimized.
In my option, event loop is provide by host environment, will check is JS engine call stack empty or not, when the stack is empty, event loop will put the job to the call stack. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This comment has been minimized.