一、概念
event:事件
loop:循环,循环的是一个又一个的任务队列
任务队列:是一个先进先出的数据结构,排在前面的事件,优先被主线程读取
任务队列分为:宏队列,微队列,分别存放宏任务和微任务
二、宏任务【多个】、微任务【1个】
微任务一般比宏任务先执行,并且微任务队列只有一个,宏任务队列可能有多个
我们常见的点击和键盘等事件也属于宏任务
1、常见宏任务
- setTimeout()
- setInterval()
- setImmediate()
- script全部代码
2、常见微任务
- promise.then()
- promise.catch()
- new MutaionObserver()
- process.nextTick()
3、本质区别
(1)宏任务特征:有明确的异步任务需要执行和回调;需要其他异步线程支持。
(2)微任务特征:没有明确的异步任务需要执行,只有回调;不需要其他异步线程支持。
4、执行顺序【这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)】
console.log = promise > promise.nextTick > promise.then > setTimeout > setImmediate
(1)先按代码顺序将同步任务压入主执行栈中执行
(2)遇到异步任务则先将异步任务压入对应的任务队列中(宏队列或微队列)
(3)同步任务执行完毕后,查看微队列,将微任务一一取出进入主执行栈中执行
(4)微任务队列清空后,再查看宏队列,只取出第一个宏任务执行,执行完一个宏任务后,回到第三步的操作
【then中的回调函数要确定Promise状态后才能压入微队列】
// Promise中的执行顺序 let promise = new Promise(function(resolve, reject) { console.log('Promise'); resolve(); }); promise.then(function() { console.log('resolved'); }); console.log('Hi!');//Promise//Hi! //resolved
//执行顺序
setTimeout(function () { console.log(1); }); new Promise(function(resolve,reject){ console.log(2) resolve(3); }).then(function(val){ console.log(val); new Promise((resolve, reject) => { console.log(5) resolve(7) }).then(res => { console.log(res); }) }) console.log(4); //先按顺序执行同步任务, //Promise新建后立即执行输出2,接着输出4,异步任务等同步任务执行完后执行, //且同一次事件循环中,微任务永远在宏任务之前执行。这时候执行栈空了,执行事件队列, // 先取出微任务,输出3,最后取出一个宏任务,输出1。
练习:
console.log('1主线程'); //整体script作为第一个宏任务进入主线程 setTimeout(function() { //setTimeout,其回调函数被分发到宏任务Event Queue(执行规则:从上到下排序,先进先执行)中 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() { //process.nextTick()其回调函数被分发到微任务Event Queue中 console.log('6微任务'); }) new Promise(function(resolve) { //Promise,new Promise直接执行,输出7 console.log('7微任务'); resolve(); }).then(function() { console.log('8微任务') //then被分发到微任务Event Queue中,排在process.nextTick微任务后面。 }) setTimeout(function() { //setTimeout,其回调函数被分发到宏任务Event Queue中,排在前面的setTimeout后面 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微任务 // 先执行微任务、再执行宏任务
标签:function,console,log,EventLoop,任务,Promise,执行,事件队列 From: https://www.cnblogs.com/le-fang/p/17477442.html