JS引擎线程

主要知识点:异步任务和同步任务

知识铺垫:
浏览器有五个线程:
Ⅰ:GUI渲染线程
Ⅱ:JS引擎线程
Ⅲ:定时触发线程
Ⅳ:浏览器事件处理线程
Ⅴ:http请求线程
除去2以外,其他的都不属于JS,而是与JS同属于浏览器,他们与JS互相配合。

首先JS引擎是单线程执行的:即一次只做一件事
举个栗子:

  function dieloop(){
    while(true){ //这是一个死循环的函数
      console.log("i")
    }
  }
  dieloop();
  console.log("I am a little weak")
  //在死循环执行时,"I am a little weak"这句话永远不能被打印出来
  //因为JS一次只处理一个任务,上一个任务没有处理完,下一个任务永远不会执行

GUI渲染线程与JS引擎线程是互斥的
GUI线程做的事情就是:凡是用户看得见的效果就是GUI线程去做的
再举个栗子

<button></button>
 //点击按钮的时候有一个按钮的专属特效,这个是GUI渲染线程渲染的
 //但是JS引擎线程在执行dieloop这个死循环时,你再去点击按钮,那个特效就没有了
 //说明在JS引擎线程运作的时候,GUI线程是冻结的

function dieloop(){
   while(true){
     console.log("i")
   }
 }
dieloop();

浏览器处理线程:它会监控click,mouse等等交互事件,当交互发生后,就会将对应的事件处理函数放入JS引擎线程里面,再有JS引擎线程去执行。

进入正题
JS是单线程运行,但是又可异步执行

当**任务是一个简单的函数时***(不涉及事件触发/网络请求/定时器)时,它就会走左边那条线,进入同步任务,被放入主线程之中***,被挨个执行

当**任务涉及事件触发/网络请求/定时器时,就会走右边那条线,进入Event Table,当事件被触发/数据被请求回来了/定时器时间到了,就会注册一个相对应的回调函数,再进入Event Queue,当主线程里面的任务被执行完毕后,再将Event Queue里面的任务,放入主线程里面,挨个执行。

当主线程里面的任务执行完毕后,它会去任务队列里面不断看有没有新的函数,如果有的话,马上执行,这个过程叫做事件循环


                                            **同步任务讲解**
    function foo(out) {

      function bar(inn) {
        console.log(inn);
      }
      
      bar("inner");
      console.log(out);
    }
    foo("outer")

    inner 
    outer

步骤:
Ⅰ.当代码没有执行时,执行栈为空。
Ⅱ:当foo执行时,创建了一帧(里面包含,形参、局部变量(预编译结果)
Ⅲ:在执行foo的内部,执行了bar
Ⅳ:创建了新的一帧,压入栈中
记住栈的特点是吃了吐,先进去的后出来,后进去的先出来
Ⅴ:bar后进去,所以先执行完,弹出栈
Ⅵ:foo再执行,执行完毕弹出栈
Ⅶ:栈为空
执行栈就等于主线程,主线程只有一条,是单线程执行运动


                                                  **异步任务讲解**

举个栗子

$.ajax(function(){
  url:××××,
  data:{},
  success:function(data){
    console.log(data);
  }
})
console.log("run");

//执行结果:
//run
//data数据

步骤:
Ⅰajax进入Event Table,注册回调函数success,这个时候就等待数据回来
Ⅱ:console.log(“run”),也是一个任务,且是一个同步任务,它进入主线程
开始执行。
Ⅲ:ajax将数据拿回来之后,http请求线程将任务放入Event Queue之中,
主线程任务执行完毕后,开始执行success函数。


                                                 **重新理解定时器**

setTimeout并不是等待时间到了之后,就直接开始执行后面的函数,而是等时间到了,将其推入浏览器线程的任务队列里面,在主线程里面的任务执行完毕后,才开始按个调用任务队列里面的函数。

  function long(){
    我执行了一分钟
  }
  setTimeout(function(){

  },100)

定时器的代码内容并不会在100ms之后就开始执行,它要等到上面long函数,再执行,所以时间是肯定大于100ms的。

即使任务队列里面没有任务,且等待时间为0ms,定时器也不可能是立刻执行的。

setInterval(function(){

},0)

也是至少4ms之后才执行,因为将定时器放入浏览器队列,再放入主线程这个过程,都需要4ms。


打出结论:执行任务的主线程是单线程,配合工作的其他线程是异步的

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值