17 js的event-loop
js的语言特性
单线程 解释性语言
event-loop
事件循环机制 由3部分组成:调用栈 微任务队列 消息队列
event-loop开始的时候,会从全局一行一行的执行 遇到函数调用 会压入到调用栈中 被压入的函数被称之为帧 当函数返回后会从调用栈中弹出
//1
function a() {
console.log(1)
}
function b() {
console.log(2)
a()
console.log(3)
}
b() // 2 1 3
- b函数调用,压入调用栈,接着输出结果2,再调用a函数,压栈,输出1,执行完毕弹出函数a,最后输出3,b函数执行完毕,弹出调用栈
js中的异步操作,比如fetch setTimeout setInterval 压入到调用栈中的时候里面的函数会进去到消息队列中去,消息队列中的任务会等到调用栈清空之后入栈再执行
//2
function c() {
setTimeout(()=>{
console.log(2)
})
a()
console.log(3)
}
c() // 1 3 2
//1. 所有同步任务都在主线程上执行,形成一个执行栈(execution context stack)。
//2. 主线程之外,还存在一个"任务队列"(task queue)。只要异步任务有了运行结果,就在"任务队列"之中放置一个事件。
//3. 一但"执行栈"中的所有同步任务执行完毕,系统就会读取"任务队列",看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
//4. 主线程不断重复上面的第三步。
//只要主线程空了,就会去读取"任务队列",这就是JavaScript的运行机制。这个过程会不断重复,这种机制就被称为事件循环(event loop)机制。
- 在1的基础上 console.log(2)加入消息队列,在函数a,函数c依次执行完成弹栈后,就执行消息队列里的消息
promise(then) async await 的异步操作会加入到微任务中去,会在调用栈清空的时候立即执行,调用栈中加入的微任务会立马执行(微任务执行优先级大于消息队列)
//3
let pro = new Promise((resolve => {
console.log('promise定义执行')
resolve(5)
}))
function d() {
setTimeout(()=>{
console.log(2)
})
a()
console.log(3)
pro.then(value => console.log(value))
}
d() //promise执行 1 3 5 2