event loop线程

参考:
阮一峰event loop
MDN Concurrency model and Event Loop
阮一峰线程和进程概念
javascript Event Loop机制详解

线程和进程

进程是指CPU所能处理的单个任务,任一时刻,CPU总是运行一个进程,而一个进程里可以有几个线程,几个线程同时进行,协同完成一个任务。

什么是event loop??

事件循环
简单说,就是在程序中设置两个线程:一个负责程序本身的运行,称为”主线程”;另一个负责主线程与其他进程(主要是各种I/O操作)的通信,被称为”Event Loop线程”(可以译为”消息线程”)
像javascript就是基于单线程的运行机制,这种模型与其他语言如c,java就有非常明显的区别。

任务队列

javascript的单线程就意味着所有的任务都需要排队,前一个执行完后一个才会执行。

image.png

这样看来,其实等待的时间甚至有时候会多于执行的时间,造成cpu空等并且后面的事项又很紧急等待的情况。
这时,javascript语言的设计者就了解到,可以先挂起正在等待返回的任务,先执行后面的任务

image.png

于是,所有任务就可以分为两种,同步任务和异步任务。同步任务是指主线程上的任务,只有前一个任务执行完毕才能执行后一个任务;异步任务是指不进入主线程,进入’任务队列‘的任务。

任务队列中的事件
image.png

像这样的机制通常运用在一些不是可以立即执行的,比如用户产生的时间,只要有指定回调函数,这些事件就会进入“任务队列”,等待主线程完成后进行读取。
任务队列也是先进先出的数据结构。

异步任务的事件

除此之外,只要是有回调函数的事件,就几乎都是异步事件,会被放进任务队列中。拿setTimeout()事件来说,这是最经典的事件了。
setTimeout()接收两个参数,第一个是回调函数,第二个是延迟时间
然而,在下面的例子中你会发现,即使延迟时间为0,还是相同的结果,这就是因为任务队列中的事件需要在主线程完成之后再执行,通过这样我们也可以看到,如果主线程任务很多,定时器的延迟时间比较短,就会出现不准的情况。

    var m = 1;
    var n = 2;
    setTimeout(function() {
          console.log(m);
    }, 0);
    console.log(n);

    //2
    //1

小试题

在一篇帖子看到的,刚开始还想不明白ヽ(≧□≦)ノ。
摘录下来。

    function foo() {
console.log('1');
bar();
setTimeout(function() {
    console.log('2');
}, 0);
Promise.resolve().then(function() {
    console.log('3');
    Promise.resolve().then(function() {
        console.log('4');
    });
});
console.log('5');
}

function bar() {
setTimeout(function() {
    console.log('6');
  }, 0);
setTimeout(function() {
    console.log('7');
  }, 0);
}

foo();

哈哈哈公布答案

image.png
Q:刚开始不明白的是为什么2是排在6和7的后面,明明bar()里面的setTimeout比直接setTimeout多一个调用级别?

后来想到,在一次调用bar()后,进入bar()函数里面,就要把该函数里的进程运行结束才会返回,所以bar()函数里面的setTimeout要运行结束才会出来继续执行任务队列里接下来的其他任务。

  • 2 一个for循环添加事件

           function send(argument) {
          console.log(argument);
      }
      var m = document.getElementById('ok');
      for (var i = 0; i < 5; i++) {
          console.log(i);   //0,1,2,3,4
          m.addEventListener('click', function () {
              console.log(i)   //5,5,5,5,5
          }) 
      }
    
这里看到不一样的输出结果,这有两方面的原因

1 是因为var声明的变量存在变量提升的问题
2 是因为js单线程所以动态添加事件的事件被挂起,直到主线程结束
解决的办法很简单,把var改为let,就不存在变量提升的问题。或者也可以从事件挂起的角度出发,找其他的解决办法如闭包

你可能感兴趣的:(event loop线程)