铜官山区建设局网站,郑州网络推广厂家,马鞍山做网站的公司78,做阿里云网站空间事件循环的工作步骤
先执行同步代码#xff0c;所有同步代码都在主线程上执行#xff0c;形成一个执行栈#xff08;又称调用栈#xff0c;先进后出#xff09;。当遇到异步任务时#xff0c;会将其挂起并添加到任务队列中#xff08;先进先出#xff09;#xff0c;…事件循环的工作步骤
先执行同步代码所有同步代码都在主线程上执行形成一个执行栈又称调用栈先进后出。当遇到异步任务时会将其挂起并添加到任务队列中先进先出宏任务放入宏任务队列微任务放进微任务队列。当执行栈为空时事件循环先从微任务队列中按顺序取出任务加入到执行栈中执行。如果微任务队列清空就从宏任务队列中取出任务加入执行栈中执行。重复上述步骤直到任务队列为空。
执行时机
微任务早于宏任务每次从宏任务队列读取任务时微任务队列都是已执行完毕清空的。 微任务执行过程中生成新的异步任务将其放在对应的队列中如果有生成新的微任务会依次将所有的微任务执行完成后再执行宏任务。 宏任务在执行过程生成新的微任务时那么这些微任务会被添加到微任务队列中等待当前这个宏任务执行完成后依次执行微任务队列。当所有微任务都执行完成后才会从宏任务队列中取出下一个任务执行。 调用栈
调用栈call stack也叫执行栈是 JavaScript 运行时用于存储函数调用的数据结构(栈先进后出)它记录了当前执行的上下文context和函数调用链。
function bar() {return 2;
}
function foo() {return bar();
}
function main() {console.log(foo());
}
main();在执行 main() 函数时它会调用 foo() 函数将 foo() 函数的调用信息添加到调用栈中。在 foo() 函数中又调用了 bar() 函数将 bar() 函数的调用信息也添加到调用栈中。最后在 bar() 函数中返回结果后将 bar() 函数的调用信息从调用栈中弹出。接着执行 foo() 函数返回结果再将 foo() 函数的调用信息从调用栈中弹出。最后main() 函数也执行完毕调用栈为空。在函数执行期间调用栈会保持不断增长和收缩的状态。
任务队列
任务队列task queue通常分为两种类型宏任务队列和微任务队列。只有异步代码才会进入任务队列然后按照先进先出的顺序执行。
代码示例
async function async1() {console.log(start); // 第1轮await async2(); // 第1轮await async3(); // 第2轮 因为上一行的await这里属于微任务放在微任务队列console.log(async111 end); // 第3轮 第2轮执行的时候因为上一行的await这里属于微任务放在微任务队列等待第3轮执行。
}
async function async2() {console.log(async222 end); // 第1轮
}
async function async3() {console.log(async333 end); // 第2轮
}
async1(); // 第一轮
setTimeout(() {console.log(setTimeout1); // 第4轮 放在宏任务队列等待微任务队列清空后执行new Promise(resolve{console.log(setTimeout1-Promise) // 第4轮 同步代码resolve(true)}.then((){console.log(setTimeout1-Promise-then) // 第5轮 微任务})
}, 0)
new Promise(resolve {console.log(Promise); // 第1轮这里属于同步代码resolve()
}).then(() {console.log(Promise111); //第2轮微任务setTimeout(() console.log(setTimeout2); // 第7轮第2轮的时候这个任务才被放在宏任务队列中在setTimeout3之后执行。})
}).then(() {console.log(Promise222); // 第3轮 第2轮执行时会将这里放在微任务队列中等待第3轮执行
})
setTimeout(() {console.log(setTimeout3); // 第6轮 宏任务本可以在第4轮宏任务一起执行由于4生成了新的微任务当4轮宏任务执行完毕后要从微任务队列中执行微任务后第5轮再执行该宏任务
}, 0)
console.log(end); // 第1轮
// start
// async222 end
// Promise
// end
// async333 end
// Promise111
// async111 end
// Promise222
// setTimeout1
// setTimeout1-Promise
// setTimeout1-Promise-then
// setTimeout3
// setTImeout2
// 第几轮的说法并不准确仅作分析思路。参考博客 JavaScript——事件循环机制Event Loop浅析