1、单线程
js是单线程,为了防止一个函数执行时间过长阻塞后面的代码,会先将同步代码放入执行栈中。再执行nextTick,再将异步代码加入异步队列中,异步队列分为微队列(Promise.then),宏队列(setTimeout ,setInterval,ajax,读取文件),然后再setImmediate
2、事件循环
分外两块:运行栈(同步),任务队列(异步)
2-1、运行栈
同步的代码是放在运行栈执行
2-2、任务队列
异步的代码放在任务队列中,通过事件循环执行,第一次
2-2-1、事件循环
是不断的检测任务队列中有没有任务,有任务就执行,有多个任务按顺序执行。
如果是计时器的话,时间到了就会放到任务队列中,然后通过事件循环检测到据执行
3、js执行步骤
- 同步(全局,promise函数体内也是同步)
- process.nextTick
- 异步(
微任务(Promise.then / awiat执行后的返回值)
宏任务(setTimeout ,setInterval,ajax,读取文件)
setImmediate(计数器放在任务队列中,第一次任务队列的事件加载完后就会触发))
)
例1:
setImmediate(()=>{
console.log(1)
})
console.log(2)
setTimeout(()=>{console.log(3)},0)//第一次放入任务队列中,事件循环加载,然后走setImmediate
setTimeout(()=>{console.log(4)},100)//100毫秒后第二次放入任务队列中,所以这个打印在setImmediate后
console.log(5)
new Promise((resolve)=>{
console.log(6) // 同步
resolve() // 加这个,promise才会走then方法
}).then(()=>{
console.log(7)
})
process.nextTick(()=>{
console.log(8)
})
输出:2、5、6、8、7、3、1、4
例2:
console.log(1)
async function main1(){
await main2()
console.log(2) //微任务,then
}
async function main2(){
console.log(3) // 这也是promise函数体
}
main1()
setTimeout(()=>{console.log(9)},100)
setTimeout(()=>{console.log(4)},0)
new Promise((resolve)=>{
console.log(5)
resolve() //加这个,promise才会走then方法
}).then(()=>{
console.log(6)
}).then(()=>{
console.log(7)
})
console.log(8)
输出:1 3 5 8 2 6 7 4 9
例3:
async created () {
console.log(1)
const d = await this.get()
console.log(d, 2)
const d1 = await this.get()
console.log(d1, 3)
},
async mounted () {
console.log(4)
const d = await this.get()
console.log(d, 5)
},
methods: {
get () {
return new Promise((resolve, reject) => {
resolve('ok')
})
}
}
输出: 1 4 ok-2 ok-5 ok-3