我们都知道js中有同步任务和异步任务,其实js还有更精细的划分,宏任务与微任务。 我们平时工作接触的比较多的
宏任务:js代码、setTimeout、setInterval
微任务:promise
我们同时也知道,js代码属于同步任务;setTimeout、setInterval和promise属于异步任务,那他们的执行顺序是什么样的呢?js执行时先执行同步任务,也就是主线程,之后执行异步线程,所以第一步先执行js代码,然后开始执行异步线程,异步线程中现在有宏任务和微任务两种任务。那么哪种先执行呢?
js的事件循环 就是先执行主线程,主线程执行完后再从 异步线程中取任务,取出来后在主线程中执行,然后不断重复,这就是事件循环。
而 宏任务与微任务呢,就是先执行宏任务,之后检查是否有微任务,如果有微任务就执行微任务,执行完微任务,再去执行下一个宏任务;如果没有微任务就继续执行下一个宏任务。
所以 上面的 promise 要比setTimeout和setInterval先执行。
下面看一段代码 这样我们能更清楚,执行顺序:
从代码上看我们要先执行宏任务的js代码,输出1;
遇到setTimeout放到宏任务队列中,称为setTimeout1;
遇到promise 输出7 .then函数放到微任务队列中;
又遇到一个setTimeout 放到 宏任务队列中 ,称为 setTimeout2;
第一个宏任务执行完,发现微任务队列中有任务 ,因此执行微任务then 输出8;
第一轮结束 。输出1、7、8
第二轮:
微任务结束,从宏任务队列中取一个宏任务执行setTimeout1 输出2;
遇到promise 输出4 then函数放到微任务中;
这个宏任务执行完,发现有微任务需要执行,则去执行then函数 输出5;
第二轮结束。输出2、4、5
第三轮
宏任务队列中还有任务setTimeout2,那么继续执行 输出9;
遇到promise 输出11 ,then放到微任务中 ;
宏任务执行完 ,执行微任务then,输出12;
第三轮结束。输出9、11、12
总结一下,输出顺序是 1、7、8、2、4、5、9、11、12
需要注意的一点是,一个宏任务执行完就去检查是否存在微任务需要执行,而不是等宏任务队列中的所有任务执行完,再去检查执行