Open diveDylan opened 5 years ago
event loop指的是js的事件运行机制,不同环境node和浏览器对这个的事件循环实现略有出入。
event loop
关于event loop就不得不说几个概念: 宏任务和微任务
宏任务macrotask,也叫task,包含以下事件:
macrotask
task
微任务microtask,包含一下事件:
microtask
new Promise
async await
测试代码输出?便于我们加深理解
const log = (e) => console.log(e) log('event start') setTimeout(() => { log('setTimeout event 1') setTimeout(() => { log('setTimeout event 2') }, 0) asy('set asycn 2', 'async event 2') }, 0); new Promise(resolve => { log('set promise') resolve() }).then(() => { log('promise evnet') setTimeout(() => { log('setTimeout event promise') }, 0) asy('set async promise', 'promise async') }) async function asy(e = 'set asycn 1', f = 'async event') { log(e) await 1 log(f) } asy()
运行这段代码在浏览器中会有如下输出:
event start set promise set asycn 1 promise evnet set async promise async event promise async setTimeout event 1 set asycn 2 async event 2 setTimeout event promise setTimeout event 2
如果跟你想象的输出一模一样,你已经了解整个event loop执行机制了。当然你也可以往下看看看本文是否有惊喜的地方。
event start
setTimeout
[setTimeout]
set promise
log
set async 1
await
awaitAsy
[ Promise, awaitAsy]
promise
promise event
[awaitAsy]
setTimeoutPromise
[setTimeout, setTimeoutPromise]
Promise
asy
set async promise
promiseAsy
[awaitAsy, promiseAys]
[setTimeout,setTimeoutPromise]
async event
[promiseAys]
[setTimeou,setTimeoutPromiset]
promiseAys
promise async
setTimeout event 1
setTimeout2
[setTimeoutPromise,setTimeout2,]
set asycn 2
setTimeoutAsy
[setTimeoutAsy]
[setTimeoutPromise,setTimeout2]
async event 2
setTimeout event promise
event loop先执行js的全局代码。遇到宏任务先推入宏任务队列,微任务推入微任务队列,微任务执行中遇到微任务,将微任务推入当前微任务队列末尾,宏任务则推入宏任务队列末尾,new Promise中的入参和async await的await前部分是同步代码,执行完所有微任务会执行第一个宏任务,按上述执行完这个宏任务的所有微任务,进入下一个宏任务
定义
event loop
指的是js的事件运行机制,不同环境node和浏览器对这个的事件循环实现略有出入。概念
关于
event loop
就不得不说几个概念: 宏任务和微任务宏任务
宏任务
macrotask
,也叫task
,包含以下事件:微任务
微任务
microtask
,包含一下事件:event loop的执行机制
new Promise
和async await
中的同步代码(起始相当于一个大的宏任务)代码测试和说明
测试代码输出?便于我们加深理解
运行这段代码在浏览器中会有如下输出:
如果跟你想象的输出一模一样,你已经了解整个
event loop
执行机制了。当然你也可以往下看看看本文是否有惊喜的地方。event start
setTimeout
,这时候的宏任务队列相当于这样的数组[setTimeout]
,setTimeout
宏任务中生成一个单独的宏任务执行栈new Promise
,这时候这里面传入函数为同步代码,输出set promise
async await
执行环境这里log
是同步代码,输出set async 1
,await
后的为微任务,微任务推入awaitAsy
,这时候微任务队列[ Promise, awaitAsy]
,宏任务[setTimeout]
promise
输出promise event
,这时候微任务队列[awaitAsy]
,遇到宏任务setTimeoutPromise
推入宏任务队列,宏任务队列[setTimeout, setTimeoutPromise]
Promise
微任务环境栈的全局代码asy
,输出set async promise
, 将微任务中新的微任务await
后部分promiseAsy
推入末尾,此时微任务队列为[awaitAsy, promiseAys]
,宏任务[setTimeout,setTimeoutPromise]
awaitAsy
,输出async event
, 微任务队列为[promiseAys]
,宏任务[setTimeou,setTimeoutPromiset]
promiseAys
,输出promise async
,微任务队列为空,执行第一个宏任务setTimeout
,执行宏任务环境栈的全局代码,输出setTimeout event 1
,宏任务队列[]setTimeout2
,推入,宏任务队列[setTimeoutPromise,setTimeout2,]
asy
的同步代码输出set asycn 2
,将await
部分微任务setTimeoutAsy
推入微任务,微任务[setTimeoutAsy]
,宏任务队列[setTimeoutPromise,setTimeout2]
setTimeoutAsy
输出async event 2
,然后执行setTimeoutPromise
, 输出setTimeout event promise
,最后执行最后的宏任务setTimeout2
总结
event loop
先执行js的全局代码。遇到宏任务先推入宏任务队列,微任务推入微任务队列,微任务执行中遇到微任务,将微任务推入当前微任务队列末尾,宏任务则推入宏任务队列末尾,new Promise
中的入参和async await
的await
前部分是同步代码,执行完所有微任务会执行第一个宏任务,按上述执行完这个宏任务的所有微任务,进入下一个宏任务