Js事件循环(Event Loop)机制

时间: 2019-10-12阅读: 372标签: 机制

前言

Event Loop是计算机系统的一种运行机制,是个很重要的概念。而JavaScript用这种机制来解决单线程运行带来的问题。理解很熟悉将会有利于我们更容易理解vue的异步事件。


JavaScript是单线程的

1、什么是单线程?

单线程在程序执行时,所走的程序路径按照连续顺序排下来,前面的必须处理好,后面的才会执行。简单来说,即同一时间只能做一件事件。

2、js为什么是单线程?

js是一种运行在网页的简单的脚本语言,由于设计的初衷是作为浏览器脚本语言,用于与用户互动,以及操作DOM。这决定它是单线程的。

3、单线程带来的问题?

单线程就意味着,所有任务都需要排队,前一个任务结束,才会执行后一个任务。如果前一个任务耗时很长,后一个任务就需要一直等着。这就会导致IO操作(耗时但cpu闲置)时造成性能浪费的问题。

4、如何解决单线程的性能问题?

采用异步可以解决。主线程完全可以不管IO操作,暂时挂起处于等待中的任务,先运行排在后面的任务。等到IO操作返回了结果,再回过头,把挂起的任务继续执行下去。于是,所有任务可以分成两种,一种是同步任务,另一种是异步任务。


执行栈和任务队列

执行栈

当执行某个函数、用户点击一次鼠标,Ajax完成,一个图片加载完成等事件发生时,只要指定过回调函数,这些事件发生时就会进入执行栈队列中,等待主线程读取,遵循先进先出原则。

任务队列

当遇到一个异步事件后,并不会一直等待异步事件返回结果,而是会将这个事件挂在与执行栈不同的队列中,我们称之为任务队列。需要注意的是异步任务必须指定回调函数,当主线程开始执行异步任务,就是执行对应的回调函数


事件循环(Event Loop)

JavaScript内存模型

在了解事件循环之前,先要弄明白js的内存模型,这有助于更好的理解事件循环。


  • 调用栈(Call Stack):用于主线程任务的执行。
  • 堆(Heap):用于存放非结构数据,如程序分配的变量和对象。
  • 任务队列(Queue): 用于存放异步任务。

js异步执行的运行机制

  1. 所有同步任务都在主线程上执行,形成一个执行栈。
  2. 主线程之外,还存在一个任务队列。只要异步任务有了运行结果,就在任务队列之中放置一个事件。
  3. 一旦执行栈中的所有同步任务执行完毕,系统就会读取任务队列,看看里面有哪些事件。那些对应的异步任务,于是结束等待状态,进入执行栈,开始执行。
  4. 主线程不断重复上面的第三步。


任务队列

异步任务分为 宏任务(macrotask)与微任务(microtask),不同的API注册的任务会依次进入自身对应的队列中,然后等待Event Loop将它们依次压入执行栈中执行。

  • 宏任务主要包含:script(整体代码)、setTimeout、setInterval、I/O、UI交互事件、setImmediate(Node.js 环境)
  • 微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)

我们的JavaScript的执行过程是单线程的,所有的任务可以看做存放在两个队列中——执行队列和事件队列。

执行队列里面是所有同步代码的任务,事件队列里面是所有异步代码的宏任务,而我们的微任务,是处在两个队列之间。

JavaScript执行时,优先执行完所有同步代码,遇到对应的异步代码,就会根据其任务类型存到对应队列(宏任务放入事件队列,微任务放入执行队列之后,事件队列之前);当执行完同步代码之后,就会执行位于执行队列和事件队列之间的微任务,然后再执行事件队列中的宏任务。

实例

new Promise(resolve => {
    resolve(1);
    
    Promise.resolve().then(() => {
        // t2
        console.log(2)
    });
    console.log(4)
}).then(t => {
    // t1
    console.log(t)
});
console.log(3);

这段代码的流程大致如下:

  1. script 任务先运行。首先遇到Promise实例,构造函数首先执行,所以首先输出了 4。此时 microtask 的任务有 t2 和 t1
  2. script 任务继续运行,输出 3。至此,第一个宏任务执行完成。
  3. 执行所有的微任务,先后取出 t2 和 t1,分别输出 2 和 1
  4. 代码执行完毕

综上,上述代码的输出是:4321


事件循环

主线程从任务队列中读取事件,这个过程是循环不断的,所以整个的这种运行机制又称为Event Loop(事件循环)。


从上图我们可以看出:

  • 主线程运行的时候,产生堆(heap)和栈(stack)。
  • 栈中的代码调用各种外部API,它们在"任务队列"中加入各种事件(click,load,done)。
  • 栈中的代码执行完毕,主线程就会去读取任务队列,依次执行那些事件所对应的回调函数


站长推荐

1.阿里云: 本站目前使用的是阿里云主机,安全/可靠/稳定。点击领取2000元代金券、了解最新阿里云产品的各种优惠活动点击进入

2.腾讯云: 提供云服务器、云数据库、云存储、视频与CDN、域名等服务。腾讯云各类产品的最新活动,优惠券领取点击进入

3.广告联盟: 整理了目前主流的广告联盟平台,如果你有流量,可以作为参考选择适合你的平台点击进入

链接: http://www.fly63.com/article/detial/6393

PHP中session机制解析

php默认用磁盘文件来实现session,在php.ini中session.save_handler = files定义session机制,sesson_start()函数是启动session的开始,session默认存放在文件中,且具有一定概率触发session的垃圾回收机制。

js对代码解析机制

脚本执行js引擎都做了什么呢?1.语法分析 2.预编译 3.解释执行。在执行代码前,还有两个步骤;语法分析很简单,就是引擎检查你的代码有没有什么低级的语法错误 ,查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined

理解Redis的内存回收机制

Redis的过期策略都有哪些?内存淘汰机制都有哪些?手写一下LRU代码实现?笔者结合在工作上遇到的问题学习分析,希望看完这篇文章能对大家有所帮助。

这一次,彻底弄懂 JavaScript 执行机制

javascript是一门单线程语言,Event Loop是javascript的执行机制.牢牢把握两个基本点,以认真学习javascript为中心,早日实现成为前端高手的伟大梦想!

浅析前端页面渲染机制

作为一个前端开发,最常见的运行环境应该是浏览器吧,为了更好的通过浏览器把优秀的产品带给用户,也为了更好的发展自己的前端职业之路,有必要了解从我们在浏览器地址栏输入网址到看到页面这期间浏览器是如何进行工作的

js继承机制的实现

说明继承的最经典的例子:几何形状。实际上,几何形状只有两种,即椭圆形(是圆形的)和多边形(具有一定数量的边)。圆是椭圆的一种,它只有一个焦点。三角形、矩形和五边形都是多边形的一种,具有不同数量的边。正方形是矩形的一种

关于JS垃圾回收机制

由于字符串、对象和数组没有固定大小,所以当它们的大小已知时,才能对它们进行动态的存储分配。JavaScript程序每次创建字符串、数组或对象时,解释器都必须分配内存来存储那个实体。

创建js hook钩子_js中的钩子机制与实现

钩子机制也叫hook机制,或者你可以把它理解成一种匹配机制,就是我们在代码中设置一些钩子,然后程序执行时自动去匹配这些钩子;这样做的好处就是提高了程序的执行效率,减少了if else 的使用同事优化代码结构

JS垃圾回收机制

找出不再继续使用的变量,然后释放掉其占用的内存。当变量进入环境(可以理解为一个函数开始执行了)时,就将这个变量标记为“进入环境”,从逻辑上讲,不能释放掉进入环境的变量,而当变量离开环境的的时候,则将其标记为离开环境。

浏览器JS事件触发机制

事件会从最外层开始发生,直到最具体的元素,也就是说假如父元素与子元素都绑定有点击事件,又互相重叠,那么先出发的会是父元素的事件,然后再传递到子元素。事件会从最内从的元素开始发生,再向外传播,正好与事件捕获相反。

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!

文章投稿关于web前端网站点搜索站长推荐网站地图站长QQ:522607023

小程序专栏: 土味情话心理测试脑筋急转弯幽默笑话段子句子语录成语大全运营推广