前端你必须要知道的进程、线程和事件队列

一、浏览器的进程和线程


      前端研发人员不要忘记了浏览器是安装在PC电脑(手机)上的应用。既然是客户端应用,就免不了一个问题:线程和进程。

  • 一个程序可以有多个进程;

  • 一个进程和多个线程;

  • 多个进程之间可以相互通信;

  • 多个线程之间可以相互通信;

  • 不同进程之间的线程不能相互通信。

      好,知道了这些基本的知识,我们来看一下浏览器(以谷歌浏览器为例)这个最基本的应用程序有哪些进程,又有哪些线程。
Chrome的进程:大家可以打开任务管理器看看,有哪些进程
在这里插入图片描述      从图中可以看到,在chrome中每打开一个标签页,每一个扩展程序都是一个进程。
Chrome的线程:对于一个进程来说,又有哪些线程呢?

  • GUI 渲染线程

  • JavaScript引擎线程

  • 定时触发器线程

  • 事件触发线程

  • 异步http请求线程

      那么当你打开一个页面,就启动了一个进程,那么这个进程有上面几个线程。这几个线程之间相互合作,但是GUI和JavaScript之间是相互独立的,而且Javascript是单线程的。原因很简单,涉及UI操作的不能同时处理,不然给用户呈现的页面会是什么样子。
      既然知道了,浏览器作为应用程序具备的基本要素。那么我们想看看浏览器内部具体的工作方式。
了解一个程序,首先了解程序的模块划分和工作流程。
浏览器主要划分这几个模块浏览器部件:那么这几个部件相互耦合,为用户提供页面。

  • 1、用户界面
  • 2、浏览器引擎
  • 3、渲染引擎
  • 4、网络
  • 5、用户界面后端
  • 6、Javascript解释器
  • 7、数据持久化存储

在这里插入图片描述

二、浏览器页面渲染的方式(页面初始化)


我们重点来看一下浏览器的渲染是怎么操作的

在这里插入图片描述
   其中重绘和重流就发生在构建阶段,重流,顾名思义,因为浏览器本身是流式布局,重流就是重新确定布局,布局主要由两个因素决定:位置和大小,所以重流是为了确定页面元素的节点位置和大小;重绘,顾名思义,重新绘制,是为了确定元素的样式,展现形式,绘制嘛。
   引发重流的因为可能因为尺寸变化(div大小改变、内容变化)、位置变化(display属性)等,重绘则是重新绘制页面样式,比如div在不同的大小情况下,会展示不同的样式。
  所以重流一定会引发重绘,重绘不一定引发重流。
  浏览器比较懒,会将重绘和重流放入队列中,然后过一段时间清空。但是有几种情况会让浏览器一定会重流和重绘,就是通过代码获取页面的元素大小,比如长宽高啊,样式啊(getComputedStyle、offset、top等)?为什么呢?因为了给用户最新的样式,如果不重绘重流,那么用户拿到的是假的。
在这里插入图片描述

三、浏览器的事件系统(页面操作)MacroMicro


在这里插入图片描述异步并不是不执行,而是执行放入队列。

四、案例(可能是你们最想看的)


//案例一:
setTimeout(() => {
    console.log(promise);
    console.log('settimeout1');
  }, 0);
let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    setTimeout(()=>{
        resolve('success');
    },0);
    //resolve('success');
  }).then((msg)=>{
    console.log('resolved.'+msg);
  });
  
  setTimeout(() => {
    console.log(promise);    
    console.log('settimeout2');
}, 0);
  console.log(promise);
  console.log('Hi!');
//输出结果
Promise                //Promise会立即执行
Promise { <pending> }  //此时promise状态为pending
Hi!                    //打印hi
Promise { <pending> }  
settimeout1            //主线程执行完毕,依次将三个settimeout放入macro队列中,打印第一个
Promise { <pending> }
settimeout2            //打印第二个
resolved.success       //promise执行成功

//案例二:

如果promise中直接resolve('success'),运行结果是怎么样?
Promise
Promise { <pending> }
Hi!
resolved.success
Promise { undefined }
settimeout1
Promise { undefined }
settimeout2

//案例三:

如果在React中的事件系统是什么样子的呢?
class Father extends Component {
  render() {
    let promise = new Promise(function(resolve, reject) {
      resolve('success1');
    }).then((msg)=>{
      console.log('resolved.'+msg);
    });
    return (
      <Son ref="son"/>
    );
  }
  componentDidMount(){
    console.log('Did Mount');
  }
  componentWillMount(){
    let promise = new Promise(function(resolve, reject) {
      resolve('success2');
    }).then((msg)=>{
      console.log('resolved.'+msg);
    });
    console.log('Will Mount');
  }
}

//输出结果
Will Mount
Did Mount
resolved.success2
resolved.success1
可以看到react并没有将micro任务合并到渲染里面

为什么会提及React,因为React 的处理方式和我们和浏览器的实现流程比较类似。
React初始化《》浏览器初始加载
React更新   《
》浏览器的事件系统
所以React从很大程度上做了一层抽象,让我们面向组件的函数编程,而不是面向浏览器的编程。

附录:Node中的事件系统Node


node环境中的事件系统多了两个 process.nextTick和setImmediate
在这里插入图片描述

//案例四:
setTimeout(() => {
    console.log(promise);
    console.log('settimeout1');
  }, 0);
let promise = new Promise(function(resolve, reject) {
    console.log('Promise');
    /*setTimeout(()=>{
        resolve('success');
    },0);*/
    resolve('success');
  }).then((msg)=>{
    console.log('resolved.'+msg);
  });
  
  setTimeout(() => {
    console.log(promise);    
    console.log('settimeout2');
}, 0);
console.log(promise);
console.log('Hi!');
process.nextTick(()=>{console.log('nextTick')});
setImmediate(()=>{console.log('Immediate')}) ;
//输出结果
Promise
Promise { <pending> }
Hi!
nextTick
resolved.success
Promise { undefined }
settimeout1
Promise { undefined }
settimeout2
Immediate
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值