js-异步

94 阅读2分钟

异步和同步的区别

什么是异步

image.png

异步和同步的区别

同步在同一时间只能做一件事,会照成代码堵塞;而异步这是可以同时做多件事,不会造成代码阻塞;

单线程

单线程就是一个线程,同一时间只能做一件事;

原因:为避免DOM渲染冲突就有了单线程;

image.png

解决单线程的方法:异步

image.png

Event Loop

  • 什么是 Event Loop

JavaScript 从 script 开始读取,然后不断循环,从 “任务队列” 中读取执行事件的过程,就是 事件循环(Event Loop)

事件循环中的异步队列有两种:宏任务队列(MacroTask)和 微任务队列(MicroTask)。宏任务队列可以有多个,微任务队列只有一个。

作用 异步回调的实现原理

image.png

image.png

image.png 宏任务 包括:

image.png

  • script
  • setTimeout
  • setInterval
  • setImmediate
  • I/O
  • UI rendering

微任务 包括:

  • MutationObserver :监听dom树变化
  • Promise.then()/catch()
  • Promise 为基础开发的其他技术,例如 fetch API
  • V8 的垃圾回收过程
  • Node 独有的 process.nextTick

image.png

image.png

image.png

image.png

image.png

image.png 循环过程

  1. 所有同步任务都在主线程上依次执行,形成一个执行栈(调用栈),异步任务处理完后则放入一个任务队列
  2. 当执行栈中任务执行完,再去检查微任务队列里的微任务是否为空,有就执行,如果执行微任务过程中又遇到微任务,就添加到微任务队列末尾继续执行,把微任务全部执行完
  3. 微任务执行完后,再到任务队列检查宏任务是否为空,有就取出最先进入队列的宏任务压入执行栈中执行其同步代码
  4. 然后回到第2步执行该宏任务中的微任务,如此反复,直到宏任务也执行完,如此循环

async/await

image.png

image.png

image.png

image.png

image.png

执行async函数,返回的是一个Promise对象

image.png

image.png

image.png

image.png

image.png

await 后面的代码都作为异步回调的函数内容;都会先放到任务队列中;await async2()这句代码的解读是:先执行函数async2,然后执行await,并且将其后面的代码都作为then()的异步函数回调;

image.png

image.png

宏任务和微任务

所有会进入的异步都是指的事件回调中的那部分代码

也就是说new Promise在实例化的过程中所执行的代码都是同步进行的,而then中注册的回调才是异步执行的。

async函数在await之前的代码都是同步执行的,可以理解为await之前的代码属于new Promise时传入的代码,await之后的所有代码都是在Promise.then中的回调

image.png

为什么微任务的执行时机比宏任务要早?

image.png

image.png

image.png

image.png

image.png

image.png