主线程
事件循环/消息队列
- 最开始的时候,渲染主线程会进入一个无限循环
- 每一次循环都会去消息队列查找是否存在任务,如果有取出第一个任务执行,然后进入下一次循环,如果没有,则进入休眠
- 其他所有线程可以向消息队列添加任务,新任务会放在消息队列的末尾,在添加新任务时,如果主线程是休息状态,则会唤醒继续拿取任务
异步
无法立即处理的任务
计时器 setTimeout setInterval
网络通信 XHR Fetch
用户操作 addEventListener
任务的优先级
- 每个任务都有一个任务类型,同一个任务类型的任务必须在一个队列,不同类型的任务可以在不同的队列,具体有多少队列由浏览器决定
- 浏览器必须有一个微队列,微队列的任务优先执行(任务队列优先执行,但是要等待主线程执行完毕)
- 延时队列(中)
- 交互队列(高)
- 微队列(最高)
添加微队列的方式
Promise.reslove().then(函数)
接下来看几道面试题
function a(){
console.log(1)
Promise.resolve().then(()=>{
console.log(2)
})
}
setTimeout(()=>{
console.log(3)
})
Promise.resolve().then(a)
console.log(5)
解析
- 渲染主线程,声名变量a,
- 将setTimeout 的回调函数放到任务队列,
- Promise.resolve.then() 将任务放到微队列,优先执行
- 输出5
- 运行微队列。执行函数a,
- 输出5,遇到Promise.resolve.then,提升到微队列
- 输出2
- 执行任务队列,输出2
答案:
// 5 1 2 3
接下来我们稍微修改一下这道题
function a(){
console.log(1)
setTimeout(()=>{
console.log(2)
})
}
setTimeout(()=>{
console.log(3)
})
Promise.resolve().then(a)
console.log(5)