从浏览器(chrome)进程机制的分析到JavaScript 运行机制

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/nick_chain/article/details/102582361

浏览器(chrome)进程机制:

浏览器作为一个软件,大家有没有好奇浏览器是多进程的还是多线程的?每打开一个浏览器页面代表着是一个线程还是一个进程呢?

其实浏览器是一个多进程软件,从开发的角度来说,相对安全的,多线程意味着大家都在'一条船上',你打开苹果的官网和三星的官网,苹果官网的页面崩溃了,三星的页面也要和你崩溃吗?无论开发者如何做多线程隔离,线程安全等等操作,整体效果没有多进程来的安全和稳定的。一般来说一个页面是一个进程,某些浏览器会做优化例如你打开同一个网址。

下面我以chrome浏览器来分析其运行机制:

首先我们打开chrome的进程管理器,打开浏览器,按下shift+esc即可,或者如图所示More Tools->Task Manager

 就出现这个Task Managerc窗口了

browser进程:浏览器的主进程,负责界面的显示,用户交互,子进程的管理,提供存储等功能

GPU Process:GPU进程,负责绘制 repaint 重绘后的 UI 界面

Utility Network:网络进程,负责页面网络资源的加载

插件进程:有插件会显示插件进程

render进程:内核进程,前端工程师开发和关注的界面,我们用户开发的进程就是在里面跑的

JavaScript 运行机制:

1.JavaScript是单线程的语言

原因:这样不仅高效率还安全。当你使用js对DOM,一个进行增加节点操作,另一个进行删除节点的操作。多线程的话会使浏览器的效率降低。多线程必然会引入的锁,信号量的一类操作,大大增加了复杂性。而浏览器是最贴近用户体验的一种软件,用户需要的是快!快!简单!简单!JavaScript设置成单线程是符合工程应用的

延伸:我们需要了解的是进程,线程,或者纤程(协程),这些都是基于操作系统的概念,不是某个语言的特点。在没有操作系统的下的编程是没有进程,线程这个说法的。例如C语言,你在Windows或者linux下的编程,有进程,线程这种说法。然而在stm32,c51/c52这种没有操作系统的环境下编程,是没有进程,线程这种说法的。

2.任务队列

单线程就意味着所有事情任务要一个个来,排队来。JavaScript把这种任务分成两种了一个是同步任务(synchronous),另一个是异步任务(asynchronous)。同步任务是在主线程上排队执行的任务,执行完一个任务才能执行下一个任务。异步任务是指不进入主线程,而是进入“任务队列”,只有“任务队列”会通知某个异步任务可以执行了才能执行,该任务会进入主线程执行

例子:

<!DOCTYPE html>

<html>
    <head>
        <script>
            console.log(11111)
            setTimeout(function(){
                console.log(2222)
            })
            console.log(333)
        </script>
    </head>
</html>

这里打印的结果会是:11111 333 2222

因为setTimeout是异步的,会进入“任务队列”,等同步任务console执行完了。才通知异步任务

同步任务执行完之前是不会执行异步任务的

例子:

<!DOCTYPE html>

<html>
    <head>
        <script>
            console.log(11111)
            
            setTimeout(function(){
                console.log(2222)
            })
            while(1){}
           // console.log(333)
        </script>
    </head>
</html>

输出结果是:11111,不会输出2222的,因为同步任务while(1)没有执行完,不会执行异步任务setTimeout的。

同步任务是一个一个执行的,前一个执行完,才到下一个执行。

<!DOCTYPE html>

<html>
    <head>
        <script>
            console.log(11111)
            /*
            setTimeout(function(){
                console.log(2222)
            })
            */
            while(1){}
            console.log(333)
        </script>
    </head>
</html>

输出的结果是:11111,不会输出333,因为同步任务while(1)没有执行完

3.深入理解Event Loop

异步执行的运行机制如下:

(1)所有同步任务会在主线程形成一个执行栈。

(2)主线程之外的任务队列只要有异步的运行结果,就在任务队列中放置一个事件

(3)执行栈中的同步任务执行完毕,系统会读取任务队列开始执行。

(4)主线程不断重复上面三个步骤

故JavaScript的运行机制:主线程从任务队列中不断循环读取事件,这种称之为事件循环(EventLoop),只要主线程空了就会读取任务队列。

参考文章:https://baijiahao.baidu.com/s?id=1615713540466951098&wfr=spider&for=pc

4.哪些属于异步任务

一般有四种:

1.setTimeout和setInterval

2.DOM事件

3.ES6中的Promise

4.Ajax异步请求

再说说JavaScript的运行过程:

1.语法分析,js会检查你是否会有语法错误这种低级错误,每个语言都会有这一步

2.预解析:将函数声明和定义整体提前,就是说在一个域内说不管你函数定义在前面,中间,后面,都会把你的函数整体提升到最前面。将变量的的声明整体提前,定义不提前。就是说在一个域内说不管你变量定义在前面,中间,后面,都会把你的变量声明提升到最前面,注意定义不提前。总结:函数定义整体提升,变量定义变量声明提升

3.找到函数的形参,将形参和实参统一

4.执行---从上到下执行(按照js运行机制)

函数定义整体提升,变量定义变量声明提升

举例:

<!DOCTYPE html>

<html>
    <head>
        <script>
            
            console.log(test)
            
            function test(){
                console.log('函数')
            }
        </script>
    </head>
</html>

虽然是在后面定义了函数,但是函数定义整体提升,js会放在前面解析,所以输出能看到test是个函数,而不是undefined之类的。

<!DOCTYPE html>

<html>
    <head>
        <script>
            
            console.log('a:'+a)

            var a = 10
        </script>
    </head>
</html>

变量定义,声明整体提升,所以a输出的是undefined,就是说a是声明了,却没有定义。(若没有声明会报错的,不会输出undefined)

总结:

js在浏览器(chrome)的render进程里面跑,js是单线程语言,js运行机制有同步任务和异步任务之分

猜你喜欢

转载自blog.csdn.net/nick_chain/article/details/102582361