美文网首页让前端飞web前端学习
深入学习JS执行,JS的单线程

深入学习JS执行,JS的单线程

作者: 烟雨丿丶蓝 | 来源:发表于2019-02-14 16:10 被阅读2次

    一、介绍

    随着js不断学习,你可能会慢慢的好奇,用了这么久的js,却不知道这js在浏览器怎么被执行的,很尴尬。所以,我查阅很多资料来总结JS的执行过程,也分享出来,和大家一起学习。

    本篇主要讲单线程的JS

    涉及的名词:JS引擎,单线程,执行栈,执行上下文(execution context)

    二、JS引擎

    JS引擎是浏览器的重要组成部分,主要用于读取并执行js。就是这家伙执行js的,但它不止于执行js。

    各大浏览器的JS引擎:

    深入学习JS执行,单线程的JS

    虽然每个浏览器的JS引擎都不同,但他们执行js机制大致相同。

    三、JS执行是单线程

    单线程是指Js引擎执行Js时只分了一个线程给他执行,也就是执行js时是单线程的。

    a.先了解线程

    • 有人可能会疑惑,线程是什么?

    直接举个例子吧,你打开一个浏览器(应用程序),那浏览器就是一个进程。打开浏览器后要做很多事情(各种分工):发送请求,接受请求,渲染页面,执行js等等这些就是一个个线程。

    我这里只是简单的说一下,具体的大家可以找计算机操作系统资料深入学习。

    b.为什么是单线程

    • 有可能有疑惑,为什么js执行要单线程,如果多线程不是可以执行得快一点吗?

    这个要回到Js历史了,布兰登·艾奇(Brendan Eich)老哥用10天创造js。当时js用来干嘛,简单的浏览器交互,验证,操作一下dom是吧。那把它设计成那么复杂干什么,而且如果多线程的话,操作dom会出现麻烦的事情,假设一个线程读取DOM节点数据的同时,另一个线程把那个DOM节点删了,呵呵。所以js一个线程就够了,也就是一步一步顺序运行下来。

    c.证明一下单线程

    单线程只能一步步执行下来,所以执行以下代码会导致阻塞(有个while死循环),不会弹出hello

    <pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; 
    font-family: Consolas, Menlo, Courier, monospace; font-size: 16px; 
    white-space: pre-wrap; position: relative; line-height: 1.5; color: rgb(153, 153, 153); 
    margin: 1em 0px; padding: 12px 10px; border: 1px solid rgb(232, 232, 232); 
    font-style: normal; font-variant: normal; font-weight: normal; 
    letter-spacing: normal; orphans: auto; text-align: start; 
    text-indent: 0px; text-transform: none; widows: 1; 
    word-spacing: 0px; -webkit-text-stroke-width: 0px; 
    background: rgb(244, 245, 246);">while(1){}
    alert('hello');</pre>
    

    四、执行栈

    实现js执行时的单线程,js引擎维护一个执行栈。(先进后出)

    来个例子:运行这段代码是执行栈是怎么做的。

    <pre style="-webkit-tap-highlight-color: transparent; box-sizing: border-box; 
    font-family: Consolas, Menlo, Courier, monospace; 
    font-size: 16px; white-space: pre-wrap; position: relative; 
    line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; 
    padding: 12px 10px; border: 1px solid rgb(232, 232, 232); 
    font-style: normal; font-variant: normal; font-weight: normal; 
    letter-spacing: normal; orphans: auto; text-align: start; 
    text-indent: 0px; text-transform: none; widows: 1; 
    word-spacing: 0px; -webkit-text-stroke-width: 0px; background: rgb(244, 245, 246);">
    //运行代码sayHello();function sayHello(){ var message = getMessage(); console.log(message);
    }function getMessage(){ return 'hello';
    }</pre>
    

    执行栈代码模拟

    <pre style="-webkit-tap-highlight-color: transparent; 
    box-sizing: border-box; font-family: Consolas, Menlo, Courier, monospace; 
    font-size: 16px; white-space: pre-wrap; position: relative; 
    line-height: 1.5; color: rgb(153, 153, 153); margin: 1em 0px; 
    padding: 12px 10px; border: 1px solid rgb(232, 232, 232); 
    font-style: normal; font-variant: normal; font-weight: normal;
    letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; 
    text-transform: none; widows: 1; 
    word-spacing: 0px; -webkit-text-stroke-width: 0px; 
    background: rgb(244, 245, 246);">
    //执行栈var exeStack = [];
    //先压如全局执行环境exeStack.push('globalContext');
    //遇到执行sayHello函数,ok,压进去exeStack.push('sayHello');
    //执行sayHello函数发现,还有个getMessage函数,ok,压进栈exeStack.push('getMessage');
    //执行完了getMessage函数,弹栈exeStack.pop();
    //继续执行sayHello函数,又发现有console.log这个家伙,ok,你进栈exeStack.push('console.log');
    //执行了console后,输出hello,console 弹栈exeStack.pop();
    //这时sayHello执行完,弹栈exeStack.pop();//最后整个代码执行完,全局环境弹栈exeStack.pop();</pre>
    

    执行栈图示:

    深入学习JS执行,单线程的JS

    这里主要是js在执行时的一个总体过程,但是你们可能会疑惑,压进栈里面的一块块(抽象)东西到底包含的是什么?
    我可以告诉你们是,执行上下文,global是指全局的的执行上下文,其他的是函数执行上下文,那到底这些上下文包含什么,我会在下一篇详解。

    五、小结

    这篇主要是将js单线程是什么,并且怎么实现单线程的,先有个总体js执行过程的印象,下一篇会详细写js执行的细节,执行上下文。

    “我自己是一名从事了6年前端的老程序员,今年年初我花了一个月整理了一份最适合2019年学习的web前端干货,从最基础的HTML+CSS+JS到移动端HTML5到各种框架都有整理,送给每一位前端小伙伴,这里是小白聚集地,欢迎初学和进阶中的小伙伴。"
    加QQ群:550389714(招募中~)

    相关文章

      网友评论

        本文标题:深入学习JS执行,JS的单线程

        本文链接:https://www.haomeiwen.com/subject/caieeqtx.html