前言

单线程语言

js是一门单线程语言,js设计之初就是为了处理浏览器网页的交互,比如DOM操作、UI动画等。如果js是多线程的,那么两个线程同时对一个DOM元素进行了相互冲突的操作,那么浏览器的解析器是无法执行的。

为什么需要异步?

单线程语言在处理同步任务的时候经常会遇到很多耗时操作,比如接口请求,定时执行等,那么我们的代码在执行的过程中会一直等待这些操作。js提供了异步的方式处理这些问题。

异步的实现方案

js实现异步的两个重要概念:eventloop事件循环,任务队列(事件队列),任务队列又分为两种:微任务和宏任务。
  • 微任务(micro-task):process.nextTick(node),Promise.then,Promise.catch,Promise.finally,MutationObserver
  • 宏任务:整体script,setTimeout,setInterval,setImmediate,I/O,UI rendering

js代码的执行过程

  • 整体代码执行一遍,既执行一个宏任务,执行过程中遇到微任务和宏任务时分别将他们添加到微任务队列和宏任务队列;
  • 整体代码执行完成后,也就是主线程为空闲时,会立即依次执行微任务队列中的任务,执行过程中又可能遇到微任务和宏任务,分别添加至微任务队列和宏任务队列;
  • 上面的过程直到微任务队列为空时,这时会根据事件循环机制获取第一个达到执行条件的宏任务,并执行,此后与整体代码执行过程完全一致。
  • 循环上面的执行过程,直到微任务队列和宏任务队列为空位置,主线程结束。

Promise微任务何时添加到微任务队列?

  • 如果Promise的状态为pending时,成功和失败的回调会存放在[[PromiseFullReactions]]和[[PromiseRejectReactions]]中,此时不能添加到微任务队列。
  • 当Promise的状态为非pending时,回调被添加至微任务队列。

promise链式调用中需要注意的问题

  • 链式调用中,只有当前一个then的回调执行完成之后,紧跟的then中的回调才会被添加到微任务队列。
  • 同一个Promise对的每一个链式调用的开端会首先一次进入微任务队列

参考文章:
https://juejin.cn/post/686957...


闲人
2 声望2 粉丝