js是单线程运行,从上到下逐步执行,js有一个:主线程,还有一个回调队列。在js中,任务分为同步任务和异步任务;
当遇到异步任务(ajax,settimeout等),会先注册异步回调函数,等异步任务执行完的时候,会把异步回调放在一个先进先出的队列里,当主线程执行完毕之后,会读取队列里的异步回调函数,这个不断重复的过程就是 event loop 事件循环。
JS的事件循环如图所示,
- 在执行主线程的任务时,如果有异步任务,会进入到Event Table并注册回调函数,当指定的事情完成后,会将这个回调函数放到 callback queue 中
- 在主线程执行完毕之后,会去读取 callback queue中的回调函数,进入主线程执行
- 不断的重复这个过程,也就是常说的Event Loop(事件循环)了
异步任务
js的异步任务,分为宏任务跟微任务、他们之间的区别主要是执行顺序的不同。
在js中
微任务
-
原生的Promise (
new Promise
在实例化的过程中所执行的代码都是同步进行的,而then
中注册的回调才是异步执行) -
process.nextTick
process.nextTick的执行优先级高于Promise的
宏任务
- 整体代码 script
- setTimeout
- setImmediate
setTimeout的执行优先级高于 setImmediate 的
宏任务与微任务的执行过程
在一次事件循环中,JS会首先执行 整体代码 script,执行完后会去判断微任务队列中是否有微任务,如果有,将它们逐一执行完后在一次执行宏任务。如此流程
大体可以这样排序
整体代码 script >
process.nextTick > Promise >
setTimeout
> setImmediate
当遇到这种类型的题目 可以先列出4行
宏任务
微任务
执行队列
输出
以一个题目为例
process.nextTick(() => { console.log('a'); setImmediate(() => { console.log('d') }) }) setImmediate(() => { console.log('b'); process.nextTick(() => { console.log('c') }) })
答案 abcd,解析过程:
一开始 执行 ,js代码放在宏任务 ,此时执行队列为空,微任务为空
宏任务 js代码
微任务
执行队列
输出
所以将宏任务中js代码放在执行队列中
宏任务
微任务
执行队列 js代码
输出
然后把 nextTick放在微任务中,setImmediate放在宏任务中
宏任务 setImmediate
微任务 nextTick
执行队列
输出
当微任务中有任务 则优先微任务 此刻有一个nextick 将他内部的内容进行解读 执行 console.log('a'); 优先输入 再将setImmediate 放入宏任务队列
宏任务 setImmediate setImmediate(console.log('d'))
微任务
执行队列 console.log('a');
输出 a
执行完执行队列 后,微任务没有任务 则看宏任务setImmediate 中有一个 console.log('b');直接执行 ,然后有一个nextTick放在微任务中
宏任务 setImmediate(console.log('d'))
微任务 nextTick
执行队列 console.log('b');
输出 a
执行微任务中的nextTick console.log('c')
宏任务 setImmediate(console.log('d'))
微任务
执行队列 console.log('c');
输出 a b c
之后微任务没有任务 继续看宏任务中的setImmediate,输出 d
宏任务
微任务
执行队列 console.log('d')
输出 a b c
所以最后的答案是 abcd
实际遇到的问题会比这个更加复杂 ,记住步骤 以及 整体代码 script >
process.nextTick > Promise >
setTimeout
> setImmediate
执行优先顺序
注意点:
new Promise
在实例化的过程中所执行的代码都是同步进行的,而then
中注册的回调才是异步执行
setTimeout(_ => console.log(4)) new Promise(resolve => { resolve() console.log(1) }).then(_ => { console.log(3) }) console.log(2)
答案是 1234
这里有一个博客 你可以很清晰得看到 运行的顺序 十分推荐 看这个
https://jakearchibald.com/2015/tasks-microtasks-queues-and-schedules/?utm_source=html5weekly
参考的相关博客 相关博客
找到了一个 博客讲的很有意思 放在这里方便以后查看
之后会继续补充