js线程任务相关知识整理

115 阅读2分钟

线程

javascript是一门单线程语言,是由前期网页需求而造成的,主要用途是负责与页面的交互,以及操作DOM(添加,删除等)。单线程在同一时间只能做一件事,这意味着,当有多个任务时,这些任务需要排队,前一个任务完成后才能继续下一个任务。

  • ”JS是单线程的”指的是JS 引擎线程。
  • 在浏览器环境中,有JS 引擎线程和渲染线程,且两个线程互斥。Node环境中,只有JS 线程。

同步任务和异步任务

同步任务 是指在主线程上排队的任务,只有前面的任务执行完毕,才能执行当前线程后面的任务。它是在同一个线程进行下去的,需要根据先后顺序执行。

异步任务 是指不进入主线程,进入任务队列的任务。只要异步任务有了运行结果,就在任务队列之中放置一个事件。

(1)所有同步任务都在主线程上执行,形成一个执行栈。
(2)主线程之外,还存在一个任务队列,只要异步任务有了结果,就会在任务队列中放置一个事件。
(3)一旦执行栈中的所有同步任务执行完毕(此时JS引擎空闲),系统就会读取任务队列,将可运行的异步任务添加到主线程(可执行栈)中,开始执行。
(4)主线程不断的重复上面的第三步

Event Loop

JS引擎常驻于内存中,等待宿主将JS代码或函数传递给它。也就是等待宿主环境分配宏观任务,反复等待 - 执行即为事件循环。

Event Loop中,每一次循环称为tick,每一次tick的任务如下:

  • 执行栈选择最先进入队列的宏任务(一般都是script),执行其同步代码直至结束;
  • 检查是否存在微任务,有则会执行至微任务队列为空;
  • 如果宿主为浏览器,可能会渲染页面(更新 render);
  • 开始下一轮tick,执行宏任务中的异步代码。

宏任务和微任务

宏任务是由宿主(JS运行的环境,一般为浏览器或者Node)发起的,而微任务由JavaScript自身发起。

宏任务(macrotask微任务(microtask
谁发起的宿主(Node、浏览器)JS引擎
具体事件1. script (可以理解为外层同步代码)1. Promise
2. setTimeout/setInterval2.MutaionObserver
3. UI rendering/UI事件3. Object.observe(已废弃;Proxy 对象替代)
4. postMessageMessageChannel4. process.nextTick(Node.js)
5. setImmediateI/O(Node.js)
谁先运行后运行先运行
会触发新一轮Tick不会
  • 在当前的微任务没有执行完成时,是不会执行下一个宏任务的。
  • 所有会进入的异步都是指的事件回调中的那部分代码