进程和线程

浏览器打开一个页面就相当于开一个“进程”(程序),在程序中,我们会同时做很多事情,每一个事情都有一个“线程”去处理,所以一个进程中可能会包含多个线程!!

浏览器是多线程的:

  • GUI渲染线程:渲染页面 & 绘制图形
  • JS引擎线程:渲染和解析JS代码
  • 事件触发线程:监听事件触发
  • 定时触发器线程:给定时器计时的
  • 异步HTTP请求线程:基于HTTP网络从服务器端获取资源和信息
  • WebWorker

同时做多件事情是“异步编程”;一次只能处理一件事,上一件事情处理完,下一件才能开始处理,这种操作是“同步编程”;

异步编程实现机制:

  • 多线程机制
    + EventLoop事件循环机制

    JS是单线程的(浏览器只分配一个线程“JS引擎线程”用来渲染和解析JS代码)

    • JS中的大部分操作都是“同步”
      + 有少部分操作,结合EventLoop机制,实现了“异步”处理
      「异步宏任务:macrotask」
      + 定时器:setTimeout/setInterval
      + 事件绑定/队列
      + 数据请求:Ajax/Fetch
      + MessageChannel
      + setImmediate「NODE」
      + …
      「异步微任务:microtask」
      + Promise.then/catch/finally
      + async/awai
      + queueMicrotask
      + MutationObserver
      + IntersectionObserver
      + requestAnimationFrame
      + process.nextTick「NODE」

第一如果宏任务之后碰到循环体 无论定时器时间是否到期 都无法执行,因为JS 是单线程的 但在循环的过程中浏览器会把之前的宏任务会依次放到EventQueue中 ,第二 **EventQueue中先执行微任务在执行宏任务**

宏任务(macrotask) 微任务(microtask)
谁发起的 宿主(Node、浏览器) JS引擎
具体事件 1. script (可以理解为外层同步代码)
2. setTimeout/setInterval
3. UI rendering/UI事件
4. postMessage,MessageChannel
5. setImmediate,I/O(Node.js)
1. Promise
2. MutaionObserver
3. Object.observe(已废弃;Proxy 对象替代)
4. process.nextTick(Node.js)
谁先运行 后运行 先运行
会触发新一轮Tick吗 不会

image.png

  1. setTimeout(() => {
  2. console.log(1);
  3. }, 20);
  4. console.log(2);
  5. setTimeout(() => {
  6. console.log(3);
  7. }, 10);
  8. console.log(4);
  9. console.time('AA');
  10. for (let i = 0; i < 90000000; i++) {
  11. // do soming
  12. }
  13. console.timeEnd('AA'); //=>AA: 79ms 左右
  14. console.log(5);
  15. setTimeout(() => {
  16. console.log(6);
  17. }, 8);
  18. console.log(7);
  19. setTimeout(() => {
  20. console.log(8);
  21. }, 15);
  22. console.log(9);

3.png