一、EventLoop的执行顺序:
- 一开始整个脚本作为一个宏任务执行
- 执行过程中同步代码直接执行,宏任务进入宏任务队列,微任务进入微任务队列
- 当前宏任务执行完出队,检查微任务列表,有则依次执行,直到全部执行完
- 执行浏览器UI线程的渲染工作
- 检查是否有
Web Worker任务,有则执行 - 执行完本轮的宏任务,回到2,依此循环,直到宏任务和微任务队列都为空
微任务包括: MutationObserver、Promise.then()或catch()、Promise为基础开发的其它技术,比如fetch API、V8的垃圾回收过程、Node独有的process.nextTick。
宏任务包括:script 、setTimeout、setInterval 、setImmediate 、I/O 、UI rendering。
注意⚠️:在所有任务开始的时候,由于宏任务中包括了script,所以浏览器会先执行一个宏任务,在这个过程中你看到的延迟任务(例如setTimeout)将被放到下一轮宏任务中来执行。
二、Promise的事件循环
Promise的状态一经改变就不能再改变。.then和.catch都会返回一个新的Promise。catch不管被连接到哪里,都能捕获上层未捕捉过的错误。- 在
Promise中,返回任意一个非promise的值都会被包裹成promise对象,例如return 2会被包装为return Promise.resolve(2)。 Promise的.then或者.catch可以被调用多次, 但如果Promise内部的状态一经改变,并且有了一个值,那么后续每次调用.then或者.catch的时候都会直接拿到该值。.then或者.catch中return一个error对象并不会抛出错误,所以不会被后续的.catch捕获。必须是如throw new Error()或是reject等才会被捕获.then或.catch返回的值不能是 promise 本身,否则会造成死循环。.then或者.catch的参数期望是函数,传入非函数则会发生值透传。.then方法是能接收两个参数的,第一个是处理成功的函数,第二个是处理失败的函数,再某些时候你可以认为catch是.then第二个参数的简便写法。.finally方法也是返回一个Promise,他在Promise结束的时候,无论结果为resolved还是rejected,都会执行里面的回调函数。new Promise()中的方法是立即执行的- 「紧跟着await后面的语句相当于放到了new Promise中,下一行及之后的语句相当于放在Promise.then中」。
- 在async函数中抛出了错误,则终止错误结果,不会继续向下执行。如果想要使得错误的地方不影响
async函数后续的执行的话,可以使用try catch
Promise.all()和Promise.race()的用法。
通俗来说,.all()的作用是接收一组异步任务,然后并行执行异步任务,并且在所有异步操作执行完后才执行回调。
.race()的作用也是接收一组异步任务,然后并行执行异步任务,只保留取第一个执行完成的异步操作的结果,其他的方法仍在执行,不过执行结果会被抛弃。
参考文章
作者:LinDaiDai_霖呆呆
链接:juejin.cn/post/684490…
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。