浏览器的进程

  1. 进程是计算机调度的基本单位,进程中包含着线程,每一个页签都是一个进程,互不影响;
  2. 浏览器也有一个主线程 (用户界面)
  3. 渲染进程:每个页签里都有一个渲染进程 (浏览器内核)
  4. 网路进程 (处理请求)
  5. GPU 进程,3d 绘制;
  6. 第三方插件的进程;

渲染进程(包含多个线程)

  1. GUI 渲染进程(渲染页面);

  2. js 引擎线程与页面渲染时互斥;

  3. 事件触发线程是独立的线程 EventLoop

  4. 事件 clicksetTimeoutajax 也是一个独立的线程;

异步任务

  1. 语言标准提供的异步方法一般都是 微任务

  2. 宿主环境提供的异步方法一般都是 宏任务

微任务

  1. promise.then

  2. process.nextTick (有可能是宏任务)

  3. MutationObserver 监视 DOM 变动

宏任务

  1. ui 渲染 (优先级较高)

  2. requestAnimationFrame (优先级较高,具体情况需要根据 屏幕的刷新频率 来判断)

  3. script 脚本

  4. ajax

  5. 事件函数

  6. setTimeout

  7. setInterval

  8. setImmediate

事件循环图解

案例分析

HTML
HTML
<body>
  <script>
    document.body.style.background = 'green';
    console.log(1);

    Promise.resolve().then(() => {
      console.log(2);
      document.body.style.background = 'red';
    });

    console.log(3);
    // 1 3 2 red(只渲染红色)
  </script>
</body>
<body>
  <script>
    document.body.style.background = 'green';
    console.log(1);

    setTimeout(() => {
      console.log(2);
      document.body.style.background = 'red';
    }, 10);

    console.log(3);
    // 1 3 2 green => red(屏幕闪烁)
  </script>
</body>

面试题

第 1 题

  1. 题目

    let n = 0;
    
    // 设置定时器的操作是同步的,但是 1S 后做的事情是异步的
    setTimeout(_ => {
        n += 10;
        console.log(n);
    }, 1000);
    
    n += 5;
    console.log(n);
    
  2. 图解

第 2 题

  1. 题目

    setTimeout(() => {
      console.log(1);
    }, 20);
    
    console.log(2);
    
    setTimeout(() => {
      console.log(3);
    }, 10);
    
    console.log(4);
    
    // 计时开始
    console.time('AA');
    for (let i = 0; i < 90000000; i++) {
      // do soming  280ms左右
    }
    // 计时结束
    console.timeEnd('AA');
    
    console.log(5);
    
    setTimeout(() => {
      console.log(6);
    }, 8);
    
    console.log(7);
    
    setTimeout(() => {
      console.log(8);
    }, 15);
    
    console.log(9);
    
  2. 图解

第 3 题

console.log(1);

setTimeout(_ => console.log(2), 50);

console.log(3);

setTimeout(_ => {
  console.log(4);
  // 遇到死循环,所有代码执行最后都是在主栈中执行,遇到死循环,主栈永远结束不了,后面啥都干不了
  while (1 === 1) { }
}, 0);

console.log(5);

第 4 题

HTML
HTML
<body>
  <button id="button">按钮</button>
  <script>
    button.addEventListener('click', () => {
      console.log('listener1');
      Promise.resolve().then(() => console.log('micro task1'))
    })
    button.addEventListener('click', () => {
      console.log('listener2');
      Promise.resolve().then(() => console.log('micro task2'))
    })
    
    button.click(); // 相当于函数执行 click1() click2(),此时并未将回调放到 宏任务队列中
    // listener1
    // listener2
    // micro task1
    // micro task2
  </script>
</body>
<body>
  <!-- 点击按钮 -->
  <button id="button">按钮</button>
  <script>
    button.addEventListener('click', () => {
      console.log('listener1');
      Promise.resolve().then(() => console.log('micro task1'))
    })
    button.addEventListener('click', () => {
      console.log('listener2');
      Promise.resolve().then(() => console.log('micro task2'))
    })
    // 点击按钮执行事件,将两个事件回调都放到了宏任务队列中,每次拿出一个执行
    // listener1
    // micro task1
    // listener2
    // micro task2
  </script>
</body>
打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 浏览器的进程
  2. 2. 渲染进程(包含多个线程)
  3. 3. 异步任务
    1. 3.1. 微任务
    2. 3.2. 宏任务
  4. 4. 事件循环图解
  5. 5. 案例分析
  6. 6. 面试题
    1. 6.1. 第 1 题
    2. 6.2. 第 2 题
    3. 6.3. 第 3 题
    4. 6.4. 第 4 题