JS的线程机制与事件机制

  • 前言
  • 一、进程与线程的概念
  • 二、浏览器内核
    • 概念
  • 三、思考定时器
    • 1. 定时器真的是定时执行的吗?
    • 2. 定时器回调函数是在哪个线程执行的?
    • 3. 定时器是如何执行的?
  • 四、JS单线程
    • 1. 如何证明JS是单线执行
    • 2. 为什么JS采用单线程执行模式?
    • 3. 代码分类
    • 4. JS执行代码的基本流程
  • 五、浏览器的事件处理机制
    • 1. js的基本处理流程
    • 2. 模型的两个重要组成部分
    • 3. 模型的运转流程
    • 4. 模型原理图
    • 5. 相关重要概念
  • 六、 H5的Web Workers(JS多线程)
    • 1. 介绍
    • 2. 相关API
    • 3. 使用步骤
      • 主线程代码
      • 分线程代码
      • 运行结果
    • 4. 不足
    • 5. 注意事项
  • 总结

前言

这篇文章主要介绍在前端JS学习过程中遇到的有关线程机制与事件机制的知识。内容围绕进程与线程、浏览器内核、定时器引发的思考、JS单线程、浏览器的事件处理机制(事件轮询)、H5 Web Workers(多线程)几个方面展开。


提示:以下是本篇文章正文内容,下面案例可供参考

一、进程与线程的概念

  1. 进程的概念
    程序的一次执行,它占有一篇独有的内存空间。可以通过Windows的任务管理器查看进程。
  2. 线程的概念
    是进程内的一个独立执行单元。(一个进程里可以运行多个线程)是程序执行的一个完整流程。是CPU的最小调度单元。
  3. 线程与进程的关系
    一个进程至少有一个线程(主线程),程序是在某个进程中的某个线程中执行的。
  4. 图解

    说明:
  • 一个程序可以启动多个进程,一个进程也可以有多个线程运行。
  • 一个程序的一个进程只有一个线程的情况,我们可以称为单线程程序(可以有多个进程,但每个进程都只有一个线程)。
  1. 相关知识
    (1)应用程序必须运行在某个进程的某个线程上。
    (2)一个进程中至少有一个运行的线程,即主线程, 主线程在进程启动后自动创建。
    (3)一个进程中也可以同时运行多个线程, 此时我们会说程序是多线程运行的。
    (4)一个进程内的数据可以供其中的多个线程直接共享。
    (5)多个进程之间的数据是不能直接共享的。
    (6)线程池(thread pool)是保存多个线程对象的容器, 实现线程对象的反复利用。
  2. 相关问题
    (1)何为多进程与多线程?
    多进程:
    一个应用程序可以同时启动多个实例运行。
    多线程:
    在一个进程内,同时有多个线程运行。
    (2)比较单线程与多线程?
    多线程
    优点:能有效提升CPU的利用率;
    缺点:创建多线程开销、线程间切换开销、死锁与状态同步问题。
    单线程
    优点:顺序编程简单易懂;
    缺点:效率低。
    (3)JS是单线程还是多线程?
    最初js是单线程运行的,但使用H5中的 Web Workers可以多线程运行。
    (4)浏览器运行是单线程还是多线程?
    所有浏览器都是多线程运行的。
    (5)浏览器运行是单进程还是多进程?
    有的是单进程,比如:firefox、老版IE
    有的是多进程,比如:chrome、新版IE
    如何查看浏览器是否是多进程运行的呢?进入Windows任务管理器–>进程

二、浏览器内核

概念

  1. 浏览器内核是支撑浏览器运行的一个最核心的程序。(本质就是一个程序)
  2. 不同浏览器内核可能不一样。如:
    Chrome,Safari:webkit内核
    firfox:Gecko内核
    IE:Trident内核
    360,搜狗等国内浏览器:Trident+webkit
  3. 内核由很多模块组成
    js引擎(js引擎也是一个代码程序,用于解释我们的程序)模块:负责js程序的编译与运行。
    html,css文档解析模块:负责页面文本的解析。
    DOM/CSS模块:负责dom/css在内存中的相关处理。(生成对象)
    布局和渲染模块:负责页面的布局和效果的绘制。
    (以上都是在主线程运行)
    ……
    定时器模块:负责定时器管理。
    DOM事件模块:负责事件的管理。
    网络请求模块:负责Ajax请求。
    (以上是在分线程运行)

三、思考定时器

1. 定时器真的是定时执行的吗?

答:

  • 定时器不能保证真正的定时执行。
  • 一般会延迟一点时间(可以接受),也有可能延迟很长时间(不能接受)。
  • 如果在主线程执行了一个长时间的操作,可能导致延时才处理。

2. 定时器回调函数是在哪个线程执行的?

答:

  • 在主线程执行,js是单线程的。

3. 定时器是如何执行的?

答:

  • 事件轮询

四、JS单线程

1. 如何证明JS是单线执行

方法:利用alert暂停主线程执行,来验证

解释:

  • setTimeout()的回调函数是在主线程执行的。
  • 定时器回调函数只有在运行栈中的初始化代码全部执行完毕后才有可能执行。

2. 为什么JS采用单线程执行模式?

答:JavaScript的单线程模式,与它的用途有关。作为浏览器脚本语言,JavaScript的主要用途是与用户互动,以及操作DOM,这决定了它只能是单线程,否则会带来很复杂的同步问题。

3. 代码分类

按照代码执行流程,可以将代码分为初始化代码和回调代码。

  • 初始化代码:程序开始就会执行;
  • 回调代码:必须在所有初始化代码执行完毕后才会执行,也称为异步执行。

4. JS执行代码的基本流程

  • 先执行初始化代码,包含一些特别的代码,如:设置定时器、绑定事件监听、发送Ajax请求等;
  • 再在后面的某个时刻(满足回调函数的执行条件后)执行回调代码。

五、浏览器的事件处理机制

浏览器的事件处理机制也称为事件轮询/循环模型。

1. js的基本处理流程

执行初始化代码==>执行回调代码

2. 模型的两个重要组成部分

事件管理模块、回调队列

3. 模型的运转流程

  • 第一步:执行初始化代码,将事件回调函数交给对应的事件管理模块管理。
  • 第二步:当对应事件发生时,事件管理模块会将回调函数及其数据添加到回调队列中。
  • 第三步:初始化代码执行完毕后(可能要一段时间),循环遍历回调队列,顺序读取队列中的回调函数并执行。

4. 模型原理图

5. 相关重要概念

  • 执行栈(execution stack),所有代码都是在此空间中执行的。
  • 浏览器内核(browser core),js引擎模块(在主线程处理),其他模块(在主线程或分线程处理)。
  • 任务队列(task queue)、消息队列(message queue)、事件队列(event queue)。
  • 事件轮询(event loop),从任务队列中循环取出回调函数放入执行栈中处理(一个接一个)。
  • 事件驱动模型(event-driven interaction model)
  • 请求响应模型(request-response model),浏览器发送请求–>服务器接收请求–>服务器处理请求–>服务器发送响应数据–>浏览器接收响应数据–>浏览器展示接收到的数据.

六、 H5的Web Workers(JS多线程)

H5规范提供了js分线程运行的实现,取名为Web Workers。

1. 介绍

Web Workers是HTML5提供的一个JavaScript多线程解决方案,我们可以将一些计算量大的代码交由Web Worker分线程运行从而不用冻结用户界面。但是分线程的执行完全受主线程控制,且无法操作DOM,所以,这个新标准并没有改变JavaScript单线程运行的本质。

2. 相关API

  • Worker():构造函数,用于加载分线程的执行文件。
  • Worker.prototype.onmessage():Worker的属性,用于接收另一个线程发来的消息。
  • Worker.prototype.postMessage():Worker的方法,向另一个线程发送消息。
  • event.data:表示消息传递的数据

3. 使用步骤

  1. 分别创建主线程与分线程的js执行文件;
  2. 在主线程使用构造函数Worker()创建对象并传递分线程执行文件的url为参数,用于加载分线程执行文件。
  3. Worker对象调用postMessage()方法,向分线程发送消息。
  4. 为Worker对象绑定onmessage事件监听,用于接收消息并展示计算结果。
  5. 在分线程修改onmessage属性为执行计算的方法,使用event.data接收主线程传来的数据并执行计算,得到数据处理结果。
  6. 在分线程执行postMessage()函数,向主线程发送消息。
  7. 调用图示:

(示例):根据用户提供的数据计算相应的斐波那契数值

主线程代码

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Web Worker练习</title></head>
<body><input type="text" id="input"><input type="button" id="btn" value="按钮"><script type="text/javascript">//获取对象var input=document.getElementById("input");var btn=document.getElementById("btn")/** 在主线程操作网页,在分线程执行计算* 主线程* */btn.onclick=function(){//创建对象,传递要调用分线程的url地址var worker=new Worker('./worker.js');//向分线程发送数据var number=input.value;worker.postMessage(number);//为对象绑定接收分线程消息的监听onmessageworker.onmessage=function(event){//输出分线程发来的消息alert("第"+number+"个数的斐波那契数值为:"+event.data);};};</script>
</body>
</html>

分线程代码

/*
* 分线程
* */
//创建斐波那契函数
function fibonacci(n){return n<=2?1:fibonacci(n-1)+fibonacci(n-2);
}
//接收主线程发送的消息onmessage
var onmessage=function(event){//创捷变量number接收主线程发来的数据var number=event.data;//执行计算var result=fibonacci(number);//向主线程发送计算结果postMessage(result);
}

运行结果


我们可以看到,当分线程执行计算第44个数的斐波那契数值时,主线程的用户界面还可以进行输入操作。利用Web Worker在分线程执行大运算量的计算,可以确保计算过程中不用冻结用户界面,保证用户的交互体验。

4. 不足

  1. 分线程的代码不能操作DOM,既不能更新UI;
  2. 不能跨域加载JS
  3. 浏览器兼容性不好

5. 注意事项

  • 主线程与分线程全局对象不同,主线程的全局对象是Window,分线程的全局对象是H5提供的对象DedicatedWorkerGlobalScope ,这也是分线程无法操作DOM的原因。
  • 由于全局对象不同,所以在分线程也不能调用Window对象的属性和方法如alert、document等。调用则会报错:
    Uncaught ReferenceError: alert is not defined at worker.js:18

总结

以上就是今天要讲的关于JS的线程机制与事件机制的学习内容。

JS的线程机制与事件机制相关推荐

  1. Ext JS学习第十六天 事件机制event(一)

    此文用来记录学习笔记: 休息了好几天,从今天开始继续保持更新,鞭策自己学习 今天我们来说一说什么是事件,对于事件,相信你一定不陌生, 基本事件是什么?就类似于click.keypress.focus. ...

  2. click事件在什么时候出发_超全的js事件机制amp;事件委托

    超全的js事件机制&事件委托,想要理解js事件只需认真看完此篇即可~ 目录结构: 什么是事件机制 事件冒泡事件捕获 DOM事件流事件委托 误区 在同一个对象上注册事件,并不一定按照注册顺序执行 ...

  3. Android事件机制详解

    转自:http://www.codeceo.com/article/android-event.html 1概述 在Android平台上,主要用到两种通信机制,即Binder机制和事件机制,前者用于跨 ...

  4. react的事件机制

    好久没写博客了,前段时间太忙以至于平时的积累都记录在内网的wiki里,趁着这几天有空,将这段时间所积累的干货慢慢的分享出来,如果内容有不正确的地方,欢迎纠正. 本博客大概介绍一下react的事件机制, ...

  5. php artisan实现机制,laravel 原理机制及几个重要功能

    Laravel作为在国内国外都颇为流行的PHP框架,风格优雅,其拥有自己的一些特点,且也发布长期支持版(LTS). 一. 请求周期 Laravel 采用了单一入口模式,应用的所有请求入口都是 publ ...

  6. 我也来说说js的事件机制

    原文链接:http://www.w3cfuns.com/notes/17398/8062de2558ef495ce6cb7679f940ae5c.html 学js,不懂事件机制,基本可以说学了js,就 ...

  7. 【JavaScript】JS事件机制学习

    常用的事件 通过事件机制,达到与用户的交互,与java的swing交互类似. 主要是结合js的函数使用. 当你添加一个事件之后没有达到想要的效果时,就要检查一下是不是给HTML标签添加了合适的事件,以 ...

  8. python 线程安全的数据类型_详解python多线程、锁、event事件机制的简单使用

    详解python多线程.锁.event事件机制的简单使用 发布时间:2020-09-25 02:04:12 来源:脚本之家 阅读:117 作者:君惜 线程和进程 1.线程共享创建它的进程的地址空间,进 ...

  9. JavaScript之JS事件机制

    JS事件机制 一.JS事件机制 1.解释 2.作用 3.内容 3.1 单双击事件 3.2 鼠标事件 3.3 键盘事件 3.4 焦点事件 3.5 页面加载事件 4.注意 5.实例 二.衍生思考 1.给合 ...

最新文章

  1. 超星未来发布新一代高级别自动驾驶车载计算平台
  2. Java并发编程的艺术 记录(一)
  3. 069 Sqrt(x) 求平方根
  4. android数据保存
  5. 心疼吗?被指是“傻X” 罗永浩深夜怒怼网友
  6. linux 常用命令练习
  7. 蓝桥杯 ALGO-98 算法训练 数位分离
  8. Wix学习整理(6)——安装快捷方式
  9. mysql 创建聚集索引_索引为什么会加快Mysql的查询速度?
  10. PTA 程序设计天梯赛(81~100题)
  11. 快速傅里叶变换(MATLAB实现)
  12. 我的USB DAC改装(MOD)流程(上)
  13. 四季电台应用项目源码
  14. Type string trivially inferred from a string literal, remove type annotation
  15. linux mysql 开发环境_RedHat Linux下QT平台MySQL数据库开发环境配置
  16. outlook邮箱邮件与企业邮箱同步(outlook本地文件夹邮件,web邮箱里没有)
  17. doodoo.js配置教程 1
  18. 怎么设置路由器当交换机用
  19. maven 出现:Failed to execute goal on project...Could not resolve dependencies for project
  20. PIXI_锚点图片位控

热门文章

  1. flash渐变制作烟雾效果
  2. 使用springboot对linux进行操控
  3. 怎么将Excel多个工作表另存为独立工作簿
  4. 多商户商城系统功能拆解41讲-平台端应用-客服设置
  5. 基于Chromium开发的称重软件,集称重、计价、打印于一体,支持耀华、顶尖等多个厂家设备型号
  6. 深搜(DFS)和宽搜(BFS)
  7. 一文深入JQuery
  8. Flash 培训教程网址
  9. 配置XP 远程桌面连接
  10. 关于“姚志浩”现象的一点看法