一、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_霖呆呆
链接:https://juejin.cn/post/6844904077537574919
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。