js中的同步任务、异步任务、宏任务、微任务
js中的同步任务、异步任务、宏任务、微任务
大部分人都知道其实js是单线程的,一段js代码都是从上往下执行的。后面js搞了异步任务,又搞了宏任务,微任务来模仿多线程。
首先js执行代码时,看当前要执行的代码是同步任务还是异步任务,当是同步任务js就会直接执行,当遇到是异步任务时,会将其放到异步任务队列中,当同步任务执行完毕,才会去执行异步任务。
在宏任务与微任务中,像我们比较常见的setTimeout和setInterval这些都是常见的宏任务,遇到这些又会将其放入宏任务队列,但是也会遇到像1. Promise2.process.nextTick(Node.js) 3. Object.observe(已废弃;Proxy 对象替代)4. MutaionObserver这些又属于微任务,当遇到这些又会将其放到微任务队列。
当同步任务执行完毕后,就会去执行微任务看有没有微任务需要执行的,当有微任务时把微任务执行完毕然后再到宏任务中去继续执行,如果宏任务中还有微任务也会将其放到微任务队列中,等宏任务执行完就会去执行微任务,然后再去宏任务,就形成了循环。
可以用下图描述
在执行栈中执行一个宏任务。
执行过程中遇到微任务,将微任务添加到微任务队列中。
当前宏任务执行完毕,立即执行微任务队列中的任务。
当前微任务队列中的任务执行完毕,检查渲染,GUI线程接管渲染。
渲染完毕后,js线程接管,开启下一次事件循环,执行下一次宏任务(事件队列中取)。
上面是自己的一些理解和看其他大佬的,我觉得用例子来说明宏任务微任务是最好理解的。
console.log('1');// 此时同步任务最先输出
setTimeout(function() {//异步任务会将其放入任务队列中
console.log('2');
process.nextTick(function() {
console.log('3');
})
new Promise(function(resolve) {
console.log('4');
resolve();
}).then(function() {
console.log('5')
})
})
process.nextTick(function() {//微任务将其放入微任务队列中
console.log('6');
})
new Promise(function(resolve) {
console.log('7');//这里是promise的初始化相当于同步任务会立即输出的
resolve();
}).then(function() {//这里是回调是微任务,会放入微任务队列中
console.log('8')
})
setTimeout(function() {//异步任务放入任务队列中
console.log('9');
process.nextTick(function() {
console.log('10');
})
new Promise(function(resolve) {
console.log('11');
resolve();
}).then(function() {
console.log('12')
})
})
第一轮同步输出 1,7
第一轮微任务输出 6,8
然后再是第一个异步任务,里面又有微任务又有宏任务 又输出2,4,3,5
最后一个异步任务 就输出 9,11,10,12
可能我自己的理解表达的不是很清楚,可以看其他大佬的如这位