Skip to content

Instantly share code, notes, and snippets.

@beetcb
Last active May 14, 2022 23:46
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save beetcb/80a0c838ffeb576dbdf3ac02b7903bdb to your computer and use it in GitHub Desktop.
Save beetcb/80a0c838ffeb576dbdf3ac02b7903bdb to your computer and use it in GitHub Desktop.
Explain event loop in JS Runtime with pseudocode
// The if-else pattern is replaced by if-only expressions for consisitency and clarity.
// A new JavaScript program or subprogram is executed, a initial task is created
taskQueue.enqueue(initParse())
// Event Loop
while everyTick {
if !callstack.isEmpty() {continue}
taskQueue.dequeue().excuteStepsByJSEngine()
while !microTaskQueue.isEmpty() {
microTaskQueue.dequeue().excuteStepsByJSEngine()
}
// Re-render process
// requestAnimationFrame task queue will be cleaned/runned before:
// - scripting(event callbacks, timer callbacks ...)
// - style calculation
// - layout
// - paint
maybeReRenderInBroswerEnvironment()
}
// Parse HTML and JS, find tasks
function initParse() {
when findNewTask {
handleTask(task)
}
}
function handleTask(task) {
if isSync(task) {
callstack.push(task)
task.excuteStepsByJSEngine()
callstack.pop()
}
if isAsync(task) {
// marcotask
if dispatchedByHost(task) {
// note!: Mutation Observer API is a host API, but will cause a microtask
waitForMessage((task with message) => {
taskQueue.enqueue(task))
})
}
// micortask
if dispatchedByJSEngine(task) || isQueueMicrotaskFunctionCall(task) {
waitForMessage((task with message) => {
microTaskQueue.enqueue(task)
})
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment