JS运行机制——运行原理

进程和线程

进程

程序的一次执行, 它占有一片独有的内存空间

线程

CPU的基本调度单位, 是程序执行的一个完整流程

进程与线程的关系

  1. 一个进程中一般至少有一个运行的线程: 主线程
  2. 一个进程中也可以同时运行多个线程, 这时程序就是多线程运行的
  3. 一个进程内的数据可以供其中的多个线程直接共享
  4. 多个进程之间的数据是不能直接共享的

浏览器运行是单进程还是多进程?

  1. 老版的大多数是单进程
  2. 新版的大多数是多进程
  3. 任务管理器 —>进程

浏览器运行是单线程还是多线程?

都是多线程运行的

JS是单线程的

验证1

  1. 定时器并非定时执行

  2. 原理:
    ① setTimeout()的回调函数是在主线程执行的
    ② 定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行

  3. 代码

    var btn = document.getElementById('btn'), timerId = null;
     btn.onclick = function (ev) {
            // 0. 清除定时器
            clearTimeout(timerId);
            // 1. 获取当前的时间
            var cTime = Date.now();
            console.log('------之前-----');
            // 2. 开启定时器
            timerId = setTimeout(function () {
                console.log((Date.now() - cTime) + 'ms后执行');
            }, 200);
            console.log('------之后-----');
    
            // 3. 耗时的任务
            for(var i = 0; i < 1000000000; i++){
    
            }
    }
    

代码划分

  1. 初始化代码
  2. 回调代码

JS引擎执行代码的基本流程

  1. 先执行初始化代码: 包含一些特别的代码
    ① 设置定时器
    ② 绑定监听
    ③ 网络(ajax)
  2. 后面在某个时刻才可能执行回调代码(异步)

验证2

// 1. 定时器1
setTimeout(function () {
    console.log('------2m');
}, 2000);
// 2. 定时器2
setTimeout(function () {
    console.log('------1m');
}, 1000);
// 3. 函数
function func() {
    console.log('--------func()');
}
func();
// 4. 弹窗
alert('阻断');
// 5. 后续操作
console.log('---------弹窗之后操作1-----');
console.log('---------弹窗之后操作2-----');

为什么JS要用单线程,不用多线程?

  1. JavaScript的单线程,与它的用途有关。
  2. 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM。
  3. 这决定了它只能是单线程,否则会带来很复杂的同步问题
    在这里插入图片描述

浏览器内核

简介

支持浏览器运行的最核心的程序
Chrome, Safari: webkit
firefox: Gecko
IE: Trident
360,搜狗等国内浏览器: Trident + webkit

内核模块组成

  1. html,css文档解析模块:负责页面文本的解析
  2. dom/css模块:负责dom/css在内存中的相关处理
  3. 布局和渲染模块:负责页面的布局和效果的绘制
  4. 定时器模块:负责定时器的管理
  5. 网络请求模块:负责服务器请求(常规/Ajax)
  6. 事件响应模块:负责事件的管理
  7. ······

事件循环模型

图示

在这里插入图片描述

了解

  1. 模型的组成
    ① 事件管理模块
    ② 回调队列
  2. 代码分类
    ① 初始化执行代码(同步代码):包含绑定dom事件监听, 设置定时器, 发送ajax请求的代码
    ② 回调执行代码(异步代码):处理回调逻辑
  3. 模型的运转流程
    ① 执行初始化代码, 将事件回调函数交给对应模块管理
    ② 当事件发生时, 管理模块会将回调函数及其数据添加到回调列队中
    ③ 只有当初始化代码执行完后(可能要一定时间), 才会遍历读取回调队列中的回调函数执行
发布了270 篇原创文章 · 获赞 123 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/KaiSarH/article/details/104442918