第四章 线程机制和事件机制

4.1 进程和线程

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

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


进程和线程:
  * 一个进程中一般至少有一个运行的线程: 主线程。
  * 一个进程中也可以同时运行多个线程, 我们会说程序是多线程运行的。
  * 一个进程内的数据可以供其中的多个线程直接共享。
  * 多个进程之间的数据是不能直接共享的。

进程和线程

4.2 JavaScript是单线程执行

1. 如何证明JavaScript是单线程执行?
   设置了定时器,定时器的回调函数会等到主线程空闲且时间到执行;
   如果主线程没有空闲下来,即使定时器的时间到了,回调函数也不会执行(等到主线程空闲)。

2. 为什么JavaScript选择单线程?
   多线程会有线程调度以及线程开启关闭的开销
   JavaScript主要在浏览器端操作DOM完成特效,如果不是单线程,不好解决页面渲染的同步问题。

4.3 事件轮询(循环)机制

事件轮询(Event Loop)是 JS 实现异步的具体解决方案,同步代码直接执行,异步函数或代码块先放在异步队列中,待同步函数执行完毕,轮询执行异步队列的函数。

执行栈(调用栈):   要执行的代码进入执行栈
回调队列: 计时器过期或者事件触发亦或者接收到ajax响应,现在回调被推送到回调队列。但是回调不会立即执行,这就是事件轮询开始的地方。
管理模块: DOM事件管理、定时器管理、ajax请求管理
事件轮询: 事件轮询的工作是监听执行堆栈,并确定执行堆栈是否为空。如果执行堆栈是空的,它将检查回调队列,看看是否有任何挂起的回调等待执行。

一道经典题目:

//问题描述:请写出最终的输出值,并解释原因
var value1 = 0, value2 = 0, value3 = 0;

for ( var i = 1; i <= 3; i++) {
  var i2 = i;
  (function() {
    var i3 = i;
    setTimeout(function() {
      value1 += i;
      value2 += i2;
      value3 += i3;
    }, 1);
  })();
}

setTimeout(function() {
        console.log(value1, value2, value3);
}, 100);

4.4 JS多线程

利用Worker可以实现多线程运算符
通过实例化一个Worker,创建一个子线程
子线程里面不允许操作DOM,也没有window
worker适合场景:
    把耗时的计算放在分线程,不会影响主线程的其他工作
    如果耗时的计算在主线程,导致页面卡顿(甚至崩溃)

worker的缺点:
    ① 无法操作DOM
    ② 无法跨域
    ③ 兼容性(不是所有的浏览器都可以使用)
Worker 构造函数
Worker.prototype.postMessage()  向分线程发送数据
Worker.prototype.onmessage      监听分线程的消息

results matching ""

    No results matching ""