术语
synchronous:同步任务、asynchronous:异步任务、task queue/callback queue:任务队列、execution context stack:执行栈、heap:堆、stack:栈、macro-task:宏任务、micro-task:微任务、Event Loop 事件循环
事件循环
-
起因:因为 js 是单线程语言,当遇到异步任务(如 ajax 操作等)时,不可能一直等待异步完成,再继续往下执行,在这期间浏览器是空闲状态,显而易见这会导致巨大的资源浪费。
-
解决方法:设定 Event Loop 规则为 javascript 的执行机制。通过执行机制解决上面问题
-
执行流程:
- 所有任务都在主线程上执行,形成一个执行栈。
- 主线程之外,还存在一个"任务队列"(task queue)。只要发现异步任务就将其放入"任务队列"中
- 一旦"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列"。那些对应的异步任务,结束等待状态,进入执行栈并开始执行。
-
ps:
- promise 主体里的代码属于同步任务, .then()里的代码才属于微任务
promise( console.log(1) // 同步任务,按顺序执行 ).then(res=>{ console.log(res) // 微任务 })- Async/Await Await 会导致其后面的代码成为微任务
async function fn1(){ console.log('1start') await fn2(); console.log('1ending') } function fn2(){ console.log('2start') console.log('2ending') } fn1(); // 1start 2start 2ending 1ending
异步任务:宏任务(macro-task)和微任务(micro-task) 任务队列:宏任务队列和微任务队列
-
不同的任务类型会依次进入自身对应的队列中,然后等待 Event Loop 将它们依次压入执行栈中执行。
-
macro-task 大概包括: script(整体代码) setTimeout setInterval setImmediate(node) I/O(node) UI render(node)
-
micro-task 大概包括: process.nextTick(node) Promise.then() Async/Await(实际就是 promise) MutationObserver(html5 新特性)