ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

线性机制与事件机制

2021-07-14 15:03:05  阅读:157  来源: 互联网

标签:执行 定时器 单线程 js 线程 事件 线性 机制 多线程


210318-20

1、进程与线程
  1. 进程(process):

    • 程序的一次执行,它占有一片独有的内存空间
    • 可以通过Windows任务管理器查看进程
  2. 线程(thread):

    • 是进程内的一个独立执行单元
    • 是程序执行的一个完整流程
    • 是CPU的最小的调度单元
  3. 图解

  4. 相关知识

    1. 应用程序必须运行在某个进程的某个线程上
    2. 一个进程中至少有一个运行的线程:主线程,进程启动后自动创建
    3. 一个进程中也可以同时运行多个线程,会说程序是多线程运行的
    4. 一个进程内的数据可以供其中的多个线程直接共享
    5. 多个进程之间的数据是不能直接共享的
    6. 线程池(thread pool):保存多个线程对象的容器,实现线程对象的反复利用
  5. 相关问题

    • 何为多进程与多线程?
      • 多进程运行:一个应用程序可以同时启动多个线程运行
      • 多线程:在一个进程内,同时有多个线程运行
    • 比较单线程与多线程?
      • 多线程
        • 优点:能有效提升CPU的利用率
        • 缺点:创建多线程开销、线程间切换开销(单核多线程,跳转运行),死锁与状态同步问题
      • 单线程
        • 优点:顺序编程简单易懂
        • 缺点:效率低
    • js是单线程还是多线程?
      • js是单线程运行的
      • 但使用h5中的web workers可以多线程运行
    • 浏览器运行时单线程还是多线程?
      • 都是多线程运行的
    • 浏览器运行是单进程还是多进程?
      • 有的是单进程:firefox,老版IE
      • 有的是多进程:chrome,新版IE
      • 如何查看浏览器是否是多进程运行的:Windows任务管理器
2、浏览器内核
  1. 支持浏览器运行的最核心的程序
  2. 不同浏览器可能不一样
    • chrome:blink
    • safari:webkit
    • firefox:Gecko
    • IE:trident
    • 360、搜狗等国内浏览器:trident(安全性高点)+webkit(双核双驱动)
  3. 内核由很多模块组成
    1. 主线程
      • js引擎模块:负责js程序的编译与运行
      • html,css文档解析模块:负责页面文本的解析
      • DOM/CSS模块:负责dom/css在内存中的相关处理
      • 布局和渲染模块:负责页面的布局和效果的绘制(内存中的对象)
    2. 分线程
      • 定时器模块:负责定时器的管理
      • DOM事件模块:负责事件的管理(异步)
      • 网络请求模块:负责ajax请求
3、定时器引发的思考
  1. 定时器并不能保持真正定时执行
  2. 一般会延迟一点(可以接受),也有可能延迟很长时间
  3. 定时器回调函数在主线程执行的,js是单线程的
  4. 定时器的实现是事件循环模型
document.getElementById('btn').onclick = function(){
    var start = Date.now()
    console.log('启动定时器前。。。')
    setTimeout(function(){
        console.log('定时器执行了',Date.now()-start)
    },200)
    console.log('启动定时器后。。。')
    //做一个长时间的操作
    for(var i = 0; i < 1000000000;i++){

    }
}
<button id="btn"></button>
4、js是单线程执行的
  1. 如何证明js执行是单线程
    • setTimeout()的回调函数是主线程执行的
    • 定时器回调函数只有在运行栈中的代码全部执行完后才有可能执行
  2. 为什么js要用单线程模式,而不是多线程模式?
    • javascript的单线程,与它的用途有关
    • 作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM(多个用户操作同一个对象是,只能是一个接一个操作,只有一个线程更新操作界面)
    • 这决定了他只能是单线程,否则会带来很复杂的同步问题
  3. 代码分类:
    • 初始化代码:包括绑定DOM时间监听,设置定时器,发送ajax请求代码
    • 回调代码:处理回调逻辑
  4. js引擎执行代码的基本流程(初始化代码-->回调代码)
    • 先执行初始化代码:包含一些特别的代码 回调函数(异步执行)
      • 设置定时器
      • 绑定事件监听
      • 发送ajax请求
    • 后面在某个时刻才会执行回调函数
setTimeout(function(){
    console.log('222222')
},2000)
setTimeout(function(){
    console.log('11111')
},1000)
setTimeout(function(){
    console.log('00000')
},0)
function fn(){
   console.log('fn()') 
}
fn()
console.log('alert()之前')
alert('-------') //暂停当前主线程的执行,同时暂停计时,点击确定后,恢复程序执行和计时
console.log('alert()之后')


5、浏览器的事件循环(轮询)模型

模型的运转流程

  • 执行初始化代码,将事件回调函数交给对应模块管理
  • 当事件发生时,管理模块会将回到函数及其数据添加到回调队列中
  • 只有当初始化代码执行完后(可能要一定时间),才会遍历读取回调队列中的回调函数执行

  1. 执行栈
    • execution stack
    • 所有的代码都是在此空间中执行的
  2. 浏览器内核
    • browser core
    • js引擎模块(在主线程处理)
    • 其他模块(在主/分线程处理)
  3. 同一个:callback queue
    • 任务队列:task queue
    • 消息队列:message queue
    • 事件队列:event queue
  4. 事件轮询
    • event loop
    • 从任务队列中循环取出回调函数放入执行栈中处理(一个接一个)
  5. 事件驱动模式
    • event-driven interaction model
  6. 请求响应模型
    • request-response model
6、H5 Web Workers(多线程)
  1. 介绍
    • h5规范提供了js多线程的实现(解决方案)取名:web workers
    • 可以将一些大计算量的代码交由web worker运行而不冻结用户界面
    • 但是子线程完全受主线程控制,且不得操作DOM(分线程中this不是window对象)。所有,这个新标准并没有改变JavaScript单线程的本质
  • 只有主线程更新界面
  1. 使用

    • 创建在分线程执行的js文件
    • 在主线程中的js中发消息并设置回调
    //web workers测试.html中
    var input = document.getElementById("number")
    document.getElementById('btn').onclick = function(){
        var number = input.value
        //创建一个worker对象并向它传递将在新线程中执行的脚本的URL
        var worker = new Worker('worker.js')
        //绑定接收消息的监听,接收worker传过来的数据函数
        worker.onmessage = function(event){
            console.log("主线程接收分线程返回的数据:"+event.data)
            alert(event.data)
        }
        //向分线程发送消息
        worker.postMessage(number)
        console.log('主线程向分线程发送数据:'+number)
    }
    
    /*创建在分线程执行的js文件worker.js*/
    function fibonacci(n){
        return n<=2 ? 1 : fibonacci(n-1) + fibonacci(n-2)//递归调用
    }
    var onmessage = function(event){//不能函数声明
        var number = event.data
        console.log('分线程接收到主线程发送的数据:'+number);
        var result = fibonacci(number)
        postMessage(result);
        console.log('分线程向主线程返回数据:'+result);
    }
    console.log(this) //不是window,不能使用window的方法alert
    //分线程中的全局对象不再是window,所以在分线程中不可能更新界面
    
    
  2. 图解

  3. 相关api

    • Worker:构造函数,加载分线程执行的js文件
    • Worker.prototype.onmessage:用于接收另一个线程的回调函数
    • Worker.prototype.postMessage:向另一个线程发送消息
  4. 不足

    • worker内代码不能操作DOM(更新UI)(全局对象不再是window)
    • 不能跨域加载js
    • 不是每个浏览器都支持这个新特性

标签:执行,定时器,单线程,js,线程,事件,线性,机制,多线程
来源: https://www.cnblogs.com/PHY01/p/15010837.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有