简单聊聊JavaScript中的事件循环

我们来谈谈JavaScript中的事件循环(Event Loop)。

什么是事件循环?

事件循环是JavaScript的一个重要的运行机制,它使得浏览器的JavaScript引擎具备操作系统调度器的功能。它不断地从任务队列中取出任务执行,直到任务队列为空。

JavaScript的事件循环是一个持续进行的过程,所以它被称为循环。而任务的来源有两种,一种是来自于浏览器内部,另一种是来自于JavaScript自己。

任务队列

任务队列分为两种:macro task(宏任务) 和 micro task(微任务)。

宏任务包括script(整体代码)、setTimeout、setInterval、setImmediate、I/O、UI rendering等。当宏任务队列中的任务执行完成后,事件循环才会去执行微任务队列。

微任务包括process.nextTick、Promise、Object.observer等。

在任务队列中,任务是按照先进先出(FIFO)的顺序执行的。

事件循环执行流程

事件循环的执行流程一般是这样的:

  1. 执行整体代码(Script)。
  2. 执行所有宏任务(macro task)。每个宏任务的执行过程都要从头到尾完成,中途不能被打断。
  3. 执行所有微任务(micro task)。每个微任务的执行过程都必须瞬间执行完成,不会存在异步等待的情况。
  4. 进行UI渲染,更新界面。

整个过程会重复执行,直到没有更多的任务需要执行。

下面我们通过两个示例来更好的理解事件循环。

示例一

console.log('script start');

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

Promise.resolve().then(function() {
  console.log('promise');
});

console.log('script end');

执行上述代码,输出结果如下:

script start
script end
promise
setTimeout

解析:

  1. 执行整体代码(Script),输出script start
  2. 执行setTimeout,由于是宏任务,将该任务放置到宏任务队列中,等待执行。
  3. 执行Promisethen回调,将该任务放置到微任务队列中,等待执行。
  4. 输出script end
  5. 此时微任务队列中的任务已经全部执行完毕,事件循环开始执行宏任务队列中的任务,先执行setTimeout,输出setTimeout

示例二

console.log('script start');

setTimeout(function() {
  console.log('setTimeout1');
  Promise.resolve().then(function() {
    console.log('promise inside setTimeout1');
  });
}, 0);

setTimeout(function() {
  console.log('setTimeout2');
  Promise.resolve().then(function() {
    console.log('promise inside setTimeout2');
  });
}, 0);

Promise.resolve().then(function() {
  console.log('promise1');
}).then(function() {
  console.log('promise2');
});

console.log('script end');

执行上述代码,输出结果如下:

script start
script end
promise1
promise2
setTimeout1
promise inside setTimeout1
setTimeout2
promise inside setTimeout2

解析:

  1. 执行整体代码(Script),输出script start
  2. 执行两个setTimeout,将它们放置到宏任务队列中,等待执行。
  3. 执行Promise的第一个then回调,将任务添加到微任务队列中,等待执行。
  4. 执行console.log('script end')
  5. 执行微任务队列中的任务,输出promise1,开始执行下一个then回调。
  6. 输出promise2
  7. 此时微任务队列已经执行完毕,事件循环开始执行宏任务队列,优先执行第一个setTimeout中的微任务:输出promise inside setTimeout1
  8. 接下来继续执行第一个setTimeout中的宏任务,输出setTimeout1
  9. 执行第二个setTimeout,将其放置到宏任务队列中等待执行。
  10. 接着我们又在第一个setTimeout的微任务队列中添加了一个任务:输出promise inside setTimeout2
  11. 执行第二个setTimeout中的宏任务,输出setTimeout2
  12. 事件循环结束,UI线程进行渲染。

希望上述两个示例可以帮助理解JavaScript中的事件循环机制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:简单聊聊JavaScript中的事件循环 - Python技术站

(0)
上一篇 2023年5月27日
下一篇 2023年5月27日

相关文章

  • JS 文字符串转换unicode编码函数

    当我们需要在JavaScript程序中使用包含非字符文本的字符串时,这些字符必须转换为Unicode编码格式。因此我们需要将字符串文本转换为Unicode格式,这就需要一个JavaScript函数来实现。 以下是一个将字符串文本转换为Unicode编码格式的JavaScript函数: function textToUnicode(text) { var un…

    JavaScript 2023年5月19日
    00
  • 80道前端面试经典选择题汇总

    80道前端面试经典选择题汇总 简介 这是一篇涵盖80道前端面试经典选择题的文章,如果你即将进行前端面试或者正在为面试做准备,本篇文章会对你有所帮助。 攻略 1. 提前了解面试形式 在面试开始前,需要了解面试的形式(例如电话面试或者现场面试)、面试官的数量,以及面试的内容等。这有助于你的面试准备。 2. 学习和掌握基础知识 在准备面试时,重点学习和掌握基础知识…

    JavaScript 2023年6月1日
    00
  • JavaScript如何实现防止重复的网络请求的示例

    要实现防止重复的网络请求,可以采用以下几种方法: Promise + debounce Promise 是 ES6 中新增加的异步编程解决方案,它可以有效地避免回调地狱的问题,通过 Promise 的方式来实现网络请求防重。而 debounce 是一个防抖函数,用来控制网络请求的触发时间间隔,防止因为用户快速连续点击而发送重复的网络请求。 下面是示例代码: …

    JavaScript 2023年5月28日
    00
  • url参数中有+、空格、=、%、&、#等特殊符号的问题解决

    针对url参数中包含特殊符号导致的问题,可以采取以下措施进行解决: 一、使用URL编码 URL编码是将URL中的非英文字母和数字都用百分号(%)加两个16进制数字表示的方式进行转换,以确保它们能够正常传输和处理。常用的URL编码方法是使用Javascript内置对象encodeURIComponent()函数。例如: https://www.example.…

    JavaScript 2023年5月19日
    00
  • JavaScript 原型继承

    JavaScript 原型继承 JavaScript 原型继承是一种非常重要的概念,相较于传统的面向对象语言中的继承,JavaScript 通过原型继承来实现对象之间的属性和方法的共享,它是 JavaScript 中最为灵活的一种继承方式。 定义 JavaScript 中的每个对象(除了 null)都有一个原型对象,原型对象可以通过 Object.getPr…

    JavaScript 2023年6月10日
    00
  • 浅谈regExp的test方法取得的值变化的原因及处理方法

    下面是“浅谈regExp的test方法取得的值变化的原因及处理方法”的完整攻略: 什么是regExp的test方法 RegExp是JavaScript中的正则表达式对象,test()是它的一个方法,用于测试一个字符串是否符合某个正则表达式的匹配规则。test()方法返回一个布尔值,如果符合规则则返回true,否则返回false。 let str = ‘abc…

    JavaScript 2023年6月10日
    00
  • js实现文字滚动的效果

    JS实现文字滚动的效果,通常可以通过CSS和JS两种方式来实现。下面将详细介绍一下这两种实现方式。 CSS实现文字滚动 1. 使用CSS动画实现文字滚动 可以通过CSS的@keyframes关键字加上animation属性来实现文字滚动的效果。具体步骤如下: 在CSS中创建一个动画实现文字滚动的效果。 @keyframes scroll { 0% { tra…

    JavaScript 2023年6月11日
    00
  • ajax异步请求详解

    AJAX异步请求详解 概念 AJAX是Asynchronous JavaScript and XML的缩写,即通过JavaScript异步发送HTTP请求,获取服务器返回的数据,再通过JavaScript动态更新页面内容,而无需刷新整个页面的技术。在AJAX中,XML通常作为数据传输格式,但也可以使用其他数据格式,如HTML、JSON等。 实现方式 要使用A…

    JavaScript 2023年6月11日
    00
合作推广
合作推广
分享本页
返回顶部