程序员

一篇文章读懂JavaScript的EventLoop

2018-05-10  本文已影响0人  似水牛年

JavaScript的单线程

众所周知JavaScript程序是单线程的执行,也就是说,同一时刻只能做一件事,这也是由于JavaScript本身就是为了浏览器而生,主要用途是用户交互和操作dom,为什么是单线程?试想如果两个线程同时操作一个dom结点,那页面页面该怎样渲染,是不是会出问题呢?

同步任务/异步任务

虽然是单线程执行,但是JavaScript本身是包含同步和异步的两种任务的,也就是说,如果一个任务耗时很长,那我们可以把这个任务放到异步去执行,后面的任务就不用等待这个任务结束,就可以执行了。

EventLoop

说完了同步任务和异步任务,那JavaScript是用怎样的机制调度执行这两种任务的呢?这里就引入了EventLoop(事件循环),我们先看下一JavaScript的引擎模型:


js-eventloop.png

下面我们来说明一下引擎模型的几个重要部分

EventLoop运行机制

  1. 所有同步任务都在主线程上执行,形成一个执行栈,如若遇到了一些异步操作像回调函数以及ajax、setTimeout等,会先将他们交给浏览器的其他模块去执行。
  2. 异步操作执行完成,就到消息队列中排队,等待执行。
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会按次序读取消息队列中的异步任务,于是被读取的异步任务结束等待状态,进入执行栈,开始执行。
  4. 主线程不断重复上面的第三步。

从代码执行顺序的角度来看,程序最开始是按代码顺序执行代码的,遇到同步任务,立刻执行;遇到异步任务,则只是调用异步函数发起异步请求。此时,异步任务开始执行异步操作,执行完成后到消息队列中排队。程序按照代码顺序执行完毕后,查询消息队列中是否有等待的消息。如果有,则按照次序从消息队列中把消息放到执行栈中执行。执行完毕后,再从消息队列中获取消息,再执行,不断重复。由于主线程不断的重复获得消息、执行消息、再取消息、再执行。所以,这种机制被称为事件循环。

事件循环讲完了,写一段代码测试一下,用最简单的setTimeout函数模拟异步操作,具体地理解一下事件循环的机制:

setTimeout(function(){console.log("1")}, 1000);
setTimeout(function(){console.log("5")}, 5000);
setTimeout(function(){console.log("2")}, 2000);
setTimeout(function(){console.log("0")});
console.log("abc");

执行结果如下,你理解事件循环了吗?

abc
0
1
2
5
上一篇 下一篇

猜你喜欢

热点阅读