强烈建议 参考:https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly
每个“线程”都有自己的事件循环,因此每个Web工作者都有自己的事件循环,因此可以独立执行,而同一源上的所有窗口都可以共享事件循环,因为它们可以同步通信。事件循环持续运行,执行所有排队的任务。事件循环具有多个任务源,这些任务源保证了该源中的执行顺序(如IndexedDB之类的规范定义了它们的执行顺序),但是浏览器可以在循环的每个循环中选择从哪个源执行任务。
计划了任务,以便浏览器可以从其内部进入JavaScript / DOM领域,并确保这些操作顺序发生。
宏任务, 微任务, JS 堆栈 ,
输出顺序日志: 宏任务 读取 开始运行脚本-》遇到setTimeOut 加入JS堆栈回调任务排队-》从上到下接着读取脚本-》遇到PROMISE.then 作为 微任务回调排队, 代码压入JS堆栈 -> 关键点: 并不是直接返回 而是 接着从上到下读取脚本->直至读取JS完毕->开始处理微任务-》第一个PROMISE.THEN 返回 , 返回会被 压入JS堆栈-》返回执行完毕 -》微任务重新读取函数 第二个PROMISE.THEN -》函数体压入JS堆栈 并准备执行, 返回被压入JS堆栈-》返回结束 ,浏览器更新渲染。
判别:
宏任务:setTimeOut ,promise 直接resolve 的函数 都会安排在 宏任务排队
微任务:attr, mutation 及action promise.then 都安排在微任务队列。