同步异步编程

125 阅读2分钟

进程&线程

  • 进程就是一个执行程序,比如浏览器中打开了一个页面就是开启了一个进程。

  • 线程是进程中具体做事情的,比如说打来页面后要做的事情。

同步&异步

  • 同步就是同一时间内只能执行一行代码,只有当前代码执行完毕之后,才会执行后面的代码。

  • 异步就是同一时间内可以执行多件事情。而JS中的异步编程并不是同一时间内执行多行代码,而是基于EventLoop事件循环和浏览器的多线程机制实现的事件监听、排队的机制。

浏览器是多线程的

  • GUI渲染线程

  • JS引擎线程 【用来执行JS代码的,也称为主线程】

  • 异步http请求线程 【ajax、fetch、jsonp】

  • webworker、 websocket

  • 定时器触发线程

  • 监听事件触发线程

......

异步任务

  1. 异步微任务 【优先级高】
  • promise「resolve/reject/then...」

  • async await

  • requestAnimationFrame 实现JS动画

  • queueMicrotask 创建一个新的异步微任务

  • IntersectionObserver 监听DOM元素和视口交叉的信息

  • MutationObserver 监听DOM元素属性改变

  • process.nextTick 【Node中的】

  • ...

  1. 异步宏任务 【优先级低】
  • 定时器 setTimeout/setInterval

  • DOM事件绑定

  • HTTP异步数据请求(ajax、fetch、jsonp...)

  • MesageChannel

  • setImmediate 【Node中的】

  • ...

EventLoop事件循环机制

  1. 浏览器打开页面之后,除了开辟堆栈内存之外,还开辟了WebAPI任务队列和EventQueue事件队列

  2. JS引擎线程【主线程】从上到下执行栈中的代码,遇到异步任务会先放到WebAPI任务队列中。然后浏览器分配相应的线程监听其是否可以执行,可以执行的话在将其挪移到EventQueue事件队列中等待执行。

  3. 执行栈中的同步任务执行完毕之后,浏览器会每隔5-7ms到EventQueue事件队列查看是否有可执行的异步任务。有的话就按照进入EventQueue事件队列中的先后顺序将其转移到执行栈中等待执行,执行完毕之后,会再次向EventQueue事件队列中取出异步任务到执行栈中。依次往复,直到EventQueue事件队列中的异步任务执行完毕。

  • EventQueue事件队列中分为异步微任务队列和异步宏任务队列

  • 异步微任务放到异步微任务队列中,异步宏任务放到异步宏任务队列中

  • 异步微任务的优先级高于异步宏任务,不论异步宏任务是否比异步微任务来的早

  • 等到异步微任务执行完毕之后,在执行异步宏任务。同一任务类型的,则按照进入队列的先后顺序执行。