【11】JavaScript 线程机制与事件机制

2019-06-27 admin

一、进程与线程

进程(process

  • 程序的一次执行,它占有一片独有的内存空间。
  • 可以通过windows任务管理器查看进程。

线程(thread

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

进程与线程图解

clipboard.png

相关知识

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

相关问题

(1)何为多进程与多线程?

  • 多进程运行:一个应用程序可以同时启动多个实例运行。
  • 多线程:在一个进程内,同时有多个线程运行。

(2)比较单线程与多线程?

  • 多线程

    • 优点:能有效提升CPU的利用率。

    • 缺点:

      • 创建多线程开销。
      • 线程间切换开销。
      • 死锁与状态同步问题。
  • 单线程

(3)JS是单线程还是多线程?

  • JS是单线程运行的。
  • 但是使用H5中的 Web Workers可以多线程运行。

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

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

  • 有的是单进程:

  • 有的是多进程:

  • 如何查看浏览器是否是多进程运行的呢?

二、浏览器内核

(1)浏览器内核是支撑浏览器运行的最核心的程序。

(2)不同的浏览器内核不一样:

  • ChromeSafariwebkit
  • FirefoxGecko
  • IETrident
  • 360,搜狗等国内浏览器:Trident+webkit

(3)内核由很多模块组成:

  • 主线程

    • js引擎模块:负责js程序的编译与运行。
    • html,css文档解析模块:负责页面文本的解析。
    • DOM/CSS模块:负责DOM/CSS在内存中的相关处理。
    • 布局和渲染模块:负责页面的布局和效果的绘制(内存中的对象)
  • 分线程

    • 定时器模块:负责定时器的管理。
    • DOM事件响应模块:负责事件的管理。
    • 网络请求模块:负责服务器请求(常规/ajax)。

三、定时器引发的思考

(1)定时器真是定时执行的吗?

  • 定时器并不能保证真正定时执行。
  • 一般会延迟一丁点(可以接受), 也有可能延迟很长时间(不能接受)。
<button id="btn">启动定时器</button>

document.getElementById('btn').onclick = function () {
  var start = Date.now()
  console.log('启动定时器前...')
  setTimeout(function () {
    console.log('定时器执行了', Date.now()-start)
  }, 200)
  console.log('启动定时器后...')
}

clipboard.png 给上面回调函数加一个长时间的任务:

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++) {}
}

结果: clipboard.png 同步任务执行完之后才会执行异步任务。

(2)定时器回调函数是在分线程执行的吗?

(3)定时器是如何实现的?

四、JS是单线程执行的

(1)如何证明js执行是单线程的?

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

(2)为什么js要用单线程模式, 而不用多线程模式?

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

(3)代码的分类:

(4)js引擎执行代码的基本流程

  • 先执行初始化代码: 包含一些特别的代码 ,回调函数(异步执行)

  • 后面在某个时刻才会执行回调代码。

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

浏览器的事件循环模型原理图

clipboard.png

相关重要概念

(1)执行栈

  • execution stack
  • 所有的代码都是在此空间中执行的。

(2)浏览器内核

  • browser core
  • js引擎模块(在主线程处理)
  • 其它模块(在主/分线程处理)

(3)任务队列(callback queue)

task queue

(4)消息队列(callback queue)

message queue

(5)事件队列(callback queue)

event queue

(6)事件轮询

  • event loop
  • 从任务队列中循环取出回调函数放入执行栈中处理(一个接一个)。

(7)事件驱动模型

event-driven interaction model

  1. (8)请求响应模型

request-response model

执行流程

(1)所有代码分类:

  • 初始化执行代码:包含绑定dom事件监听, 设置定时器, 发送ajax请求的代码。
  • 回调执行代码:处理回调逻辑。

(2)js引擎执行代码的基本流程:

(3)模型的2个重要组成部分:

(4)模型的运转流程

​ (a)执行初始化代码, 将事件回调函数交给对应模块管理。

​ (b)当事件发生时, 管理模块会将回调函数及其数据添加到回调列队中。

​ (c)只有当初始化代码执行完后(可能要一定时间), 才会遍历读取回调队列中的回调函数执行。

六、H5 Web Workers(多线程)

介绍

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

使用

  • 相关API

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

var onmessage = function (event){ //不能用函数声明
    console.log('onMessage()22');
    var upper = event.data.toUpperCase();//通过event.data获得发送来的数据
    postMessage( upper );//将获取到的数据发送回主线程
}
//创建一个Worker对象并向它传递将在新线程中执行的脚本的URL
var worker = new Worker("worker.js");  
//接收worker传过来的数据函数
worker.onmessage = function (event) {     
    console.log(event.data);             
};
//向worker发送数据
worker.postMessage("hello world");    

图解

clipboard.png

应用练习

编程实现斐波那契数列(Fibonacci sequence)的计算

F(0)=0,F(1)=1,..... F(n)=F(n-1)+F(n-2)
var fibonacci =function(n) {
    return n <2 ? n : fibonacci(n -1) + fibonacci(n -2);
};
console.log(fibonacci(48));
  • 使用Web Workers在分线程:

    var worker = new Worker('worker2.js');
    worker.addEventListener('message', function (event) {
        var timer2 = new Date().getTime();
        console.log('结果:' + event.data, '时间:' + timer2, '用时:' + ( timer2 - timer ));
    }, false);
    var timer = new Date().getTime();
    console.log('开始计算: ', '时间:' + timer);
    setTimeout(function () {
        console.log('定时器函数在计算数列时执行了', '时间:' + new Date().getTime());
    }, 1000);
    worker.postMessage(40);
    console.log('我在计算数列的时候执行了', '时间:' + new Date().getTime());
    
    var fibonacci =function(n) {
        return n <2 ? n : fibonacci(n -1) + fibonacci(n -2);
    };
    var onmessage = function(event) {
        var n = parseInt(event.data, 10);
        postMessage(fibonacci(n));
    };
    

不足

  • 慢。
  • 不能跨域加载JS
  • worker内代码不能访问DOM(更新UI)。
  • 不是每个浏览器都支持这个新特性。

[转载]原文链接:https://segmentfault.com/a/1190000019600459

本站文章除注明转载外,均为本站原创或编译。欢迎任何形式的转载,但请务必注明出处。

转载请注明:文章转载自 JavaScript中文网 [https://www.javascriptcn.com]

本文地址:https://www.javascriptcn.com/read-68346.html

文章标题:【11】JavaScript 线程机制与事件机制

相关文章
JavaScript教程:JS中的原型
Keith Peters 几年前发表的一篇博文,关于学习没有“new”的世界,其中解释了使用原型继承代替构造函数。两者都是纯粹的原型编码。 标准方法(The Standard Way) 一直以来,我们学习的在 JavaScript 里创建对...
2015-11-12
javascript是什么意思
avaScript是Netscape开发的一个对象脚本语言,它使用在世界各地数以百万计的网页和服务器应用程序上。 网景的JavaScript是ecma - 262版的标准脚本语言,和公布的标准只有轻微的差异。 与广为流行的错误理解相反,Ja...
2015-11-12
21天学通javascript
简介: 本书是Javascript入门教程。Javascript是Web开发中应用最早、发展最成熟、用户最多的脚本语言。其语法简洁,代码可读性在众多脚本语言中最好,它在使用时不用考虑数据类型,是真正意义上的动态语言。本书总分为四篇,共21章...
2015-11-16
Node.js学习(1)----HTTP服务器与客户端
Node.js 标准库提供了 http 模块,其中封装了一个高效的 HTTP 服务器和一个简易的HTTP 客户端。http.Server 是一个基于事件的 HTTP 服务器,它的核心由 Node.js 下层 C++部分实现,而接口由 Jav...
2015-11-12
JavaScript的组成
一个完整的JavaScript由3个部分组成:核心(ECMAScript) 文档对象模型(DOM) 浏览器对象模型(BOM) ECMAScript 描述了该语言的语法和基本对象 ; DOM 描述了处理网页内容的方法和接口 ; BOM 描...
2015-11-12
javaScript+turn.js实现图书翻页效果实例代码
为了实现图书翻页的效果我们在网上可以看到很多教程 在这里推荐turn.js 网上的turn.js 有api 不过是英文的  很多人看起来不方便 .关于代码也是奇形怪状在这里我将详细讲解如何使用turn.js实现翻页效果 ,本篇文章只是讲解 ...
2017-03-16
JavaScript 事件流、事件处理程序及事件对象总结
JS与HTML之间的交互通过事件实现。事件就是文档或浏览器窗口中发生的一些特定的交互瞬间。可以使用监听器(或处理程序)来预定事件,以便事件发生时执行相应的代码。这种在传统软件工程中被称为观察员模式,支持页面的行为与页面的外观之间的松散耦合。...
2017-04-05
JavaScript变量的声明
声明变量 变量在脚本中的首次亮相是在其声明中。 在变量首次出现时将会在内存中设置它,因此您稍后可在脚本中引用它。 应在使用变量之前先声明变量。 可以使用 var 关键字实现此目的。 &lt;span id=“mt9” class=“sent...
2015-11-12
7个提高效率的JavaScript调试工具
鐜板湪鐨凧avaScript浜嬪疄涓婂凡鐒舵垚涓轰簡娴佽�岀殑web璇�瑷€锛屽嵆浣垮畠骞朵笉瀹岀編銆傚緢澶氱▼搴忓憳涓嶅枩娆㈢敤JavaScript鍐欎唬鐮侊紝鏄�鍥犱负鍐欏埌鍚庢潵鎬讳細鍑虹幇鍚勭�嶈帿鍚嶅叾濡欑殑bug锛岃€屼笖鍦ㄥ紑...
2015-11-11
Web前端开发与iOS终端开发的异同
毕业之前一直在做前端开发,毕业后就转成做iOS开发,这两者有很多挺有意思的对比,尝试写下我能想到的它们的一些相同点和不同点。 语言 前端和终端作为面向用户端的程序,有个共同特点:需要依赖用户机器的运行环境,所以开发语言基本上是没有选择的,...
2016-01-13
回到顶部