运行机制:
- JS 的本质是单线程执行
- 事件队列:同步任务,异步任务()
运行机制
1,JS 的本质是单线程执行
单线程就意味着所有任务需要排队,前一个任务结束,才会执行下一个任务。
宿主:JS运行的环境,一般为浏览器或者Node。即为宿主;
2,执行的过程
- 一般来说,非阻塞性的任务采取同步的方式,直接在主线程的执行完成。
- 一般来说,阻塞性的任务都会采用异步来执行,异步的工作一般会交给其他线程完成,然后回调函数会放到事件队列中。
- 等主线程完成之后,Event Loop再把操作事件队列中返回的结果,拿来进行处理
3,事件队列
同步任务:非阻塞性的任务采取同步的方式
异步任务:阻塞性的任务都会采用异步来执行
循环执行的任务:
- 执行栈选择最先进入队列的宏任务(一般都是script),执行同步代码直至结束;
- 检查是否存在微任务,有则会执行至微任务队列为空;
- 如果宿主为浏览器,可能会渲染页面;
- 开始下一轮tick,执行宏任务中的异步代码(setTimeout等回调)
宏任务 与 微任务
1,定义
宏任务:宏任务是由宿主发起的,会再次执行事件队列,执行同步事件
微任务:微任务由JavaScript自身发起,不会再次执行该事件队列,执行异步事件
2,常见的任务
- 常见的宏任务:定时器(下一个宏任务,宏任务是当前的主线程)
- 常见的微任务:promise.then
3,两者关系
- 宏任务:宏任务里面可以带着微任务
- 微任务:微任务依附于宏任务
4,执行过程
- 执行的循环过程:宏任务(主线程代码)=>可执行的微任务=>执行所有的微任务=>开始新的宏任务
案例
setTimeout(function() {
console.log('1')
}, 0)
console.log('2')
new Promise(resolve => {
console.log('3')
resolve()
}).then(function() {
console.log('4')
})
console.log('5')
`输出顺序是:2,5,3,4,1`
注:promise 是主线程;promise.then/catch/finally 微任务
new Promise(function(resolve,reject){
console.log(123) // 此时 promise 还在主线程上
resolve()
}).then(function(){ // 此时 .then 是微任务
console.log(4567)
})