浏览器脚本运行时间长 JavaScript运行原理:浏览器事件循环机制(Event Loop),超详细
5、事件触发线程
浏览器Event Loop图:
示例代码:
1. 初始化状态都为空,浏览器控制台是空的的浏览器脚本运行时间长,调用堆栈也是空的
2. console.log(‘Hi’)添加到调用堆栈中
3. 执行console.log(‘Hi’)
4. console.log(‘Hi’)从调用堆栈中移除。
5. setTimeout(function cb1() { … }) 添加到调用堆栈。
6. setTimeout(function cb1() { … }) 执行,浏览器创建一个计时器计时,这个作为Web api的一部分。
7. setTimeout(function cb1() { … })本身执行完成,并从调用堆栈中删除。
8. console.log(‘Bye’) 添加到调用堆栈
9. 执行 console.log(‘Bye’)
10. console.log(‘Bye’) 从调用调用堆栈移除
11. 至少在5秒之后,计时器完成并将cb1回调推到回调队列。
12. 事件循环从回调队列中获取cb1并将其推入调用堆栈。
13. 执行cb1并将console.log(‘cb1’)添加到调用堆栈。
14. 执行 console.log(‘cb1’)
15. console.log(‘cb1’) 从调用堆栈中移除
16. cb1 从调用堆栈中移除
快速回顾:
宏任务和微任务
在JavaScript中辅助论坛,任务被分为Task(又称为MacroTask,宏任务)和MicroTask(微任务)两种。它们分别包含以下内容:
MacroTask: script(整体代码), setTimeout, setInterval, setImmediate(node独有), I/O, UI rendering
MicroTask: process.nextTick(node独有), Promises, Object.observe(废弃), MutationObserver
需要注意的一点是:
在同一个上下文中,总的执行顺序为同步代码—>microTask—>macroTask
具体来说,浏览器会不断从task队列中按顺序取task执行,每执行完一个task都会检查microtask队列是否为空(执行完一个task的具体标志是函数执行栈为空),如果不为空则会一次性执行完所有microtask。然后再进入下一个循环去task队列中取下一个task执行,以此类推。
示例代码:
主程序和和settimeout都是宏任务浏览器脚本运行时间长,两个promise是微任务
第一个宏任务(主程序)执行完,执行全部的微任务(两个promise),再执行下一个宏任务(settimeout),所以结果为:
正确答案是
script start, script end, promise1, promise2, setTimeout
来源:【九爱网址导航www.fuzhukm.com】 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!