JavaScript基础——异步任务的执行顺序
一、概念
JavaScript是单线程语言,只能一行一行代码执行,这就会造成代码阻塞,比如一个页面加载数据必须要第一个数据加载出来才能加载下一个数据,这样就会导致用户体验很差。这时候就需要通过异步来解决这个问题了。
那么什么是异步呢?
JavaScript分为同步和异步任务
同步任务:在主线程上排队执行的任务,只有前一个任务执行完毕才能执行下一个任务
异步任务:不进入主线程,进入由事件触发线程管理的一个任务队列,通过”任务队列“通知主线程,某个异步任务就可以执行了,该任务才会进入主线程执行。
二、JavaScript任务的执行顺序
-
JavaScript的宏任务和微任务
宏任务:包括整体代码script、setTimeout、setInterval等
微任务:Promise(then、catch),async/await中await后面部分
-
demo
console.log(111); setTimeout(function() { console.log(222) },1000); new Promise(function(resolve) { console.log(333); resolve(); } ).then(function() { console.log(444) }); console.log(555);
demo解析:首先输出111 ,然后将setTimeout列入宏任务往下执行Promise,输出333,通过resolve()将then列入微任务,往下执行,输出555,代码执行结束,此时宏任务有set,微任务有then,首先查看微任务,有则先执行微任务,输出444,执行结束继续询问是否有微任务,没有则执行宏任务输出222.
所以输出顺序为:111=》333=》555=》444=》222
-
demo进阶
async function async1 () { console.log('async1 start'); await async2(); console.log('async1 end') } async function async2 () { console.log('async2') } console.log('script start'); setTimeout(function () { console.log('setTimeout') }, 0); async1(); new Promise(function (resolve) { console.log('promise1'); resolve() }).then(function () { console.log('promise2') }); console.log('script end')
demo解析:首先执行js第一个宏任务,遇到async则先不执行,首先输出了script start,遇到setTimeout列入宏任务,继续向下执行async1函数,输出async1 start,遇到await执行async2输出async2将输出async1 end列入微任务继续向下执行,遇到Promise立即执行输出promise2将then列入微任务,然后输出script end
最后微任务:输出async1 end、then;宏任务:setTimeout,先依次执行微任务,输出async1 end、输出promise2,微任务执行完,最后执行宏任务输出setTimeout。
最后输出结果:script start、async1 start、async2、promise2、script end、async1 end、promise2、setTimeout
总结:
总结一下异步任务的执行顺序,首先会执行第一次宏任务,然后将一些微任务和宏任务列入队列,当第一次宏任务执行完毕,查看微任务是否有任务,有则依次执行微任务,当微任务执行完毕,则查看宏任务是否有任务,有则执行宏任务队列的任务,执行完毕后程序解决。