简单聊聊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日

相关文章

  • 使用JavaScript计算前一天和后一天的思路详解

    十分感谢您的提问,我将为您提供如下对“使用JavaScript计算前一天和后一天的思路详解”的详细讲解攻略。 简介 首先,我们需要了解一下时间相关的标准,JavaScript中常见的有三种时间格式:时间戳、日期时间字符串、Date对象。其中,时间戳(Unix Timestamp / Epoch Time)一般指的是从1970年1月1日00:00:00至现在的…

    JavaScript 2023年5月27日
    00
  • js中遍历Map对象的简单实例

    下面我详细讲解一下“JS中遍历Map对象的简单实例”的完整攻略。 1. 什么是Map对象 在JavaScript中,Map对象提供了一种类似字典的数据结构,可以用来存储键值对。Map对象中的键名可以为任何数据类型。而普通对象的键名只能是字符串或者 Symbol 类型。与普通对象不同的是,Map对象中的元素是按照插入顺序存储的。下面是一个Map对象的初始化示例…

    JavaScript 2023年5月27日
    00
  • 详解JS函数stack size计算方法

    详解JS函数stack size计算方法 栈大小及其作用 在JS中,每当函数调用时,就会创建一个称为“栈帧”的数据结构,用于存储调用状态和参数等信息。栈帧是一种后进先出的数据结构,用于保存函数调用链的关系。栈帧的大小取决于函数中使用的变量数量和它们的类型。 当一个函数被调用时,它会在当前栈顶位置创建一个新的栈帧。当函数返回时,栈帧会被弹出,将控制权返回给调用…

    JavaScript 2023年6月11日
    00
  • js验证身份证号码记录的方法

    下面我将为你详细讲解 “js验证身份证号码记录的方法” 的完整攻略。 一、验证身份证号码的规则 目前,中国大陆身份证号码的规则如下: 身份证号码共18位,前17位为数字,最后一位为数字或字母X。 第1-6位为地址码,表示身份证持有人的籍贯地。 第7-14位为出生日期码,表示身份证持有人的出生年月日。 第15-17位为顺序码,表示同一地址码的多个人员的顺序区分…

    JavaScript 2023年6月10日
    00
  • JavaScript中的Primitive对象封装介绍

    下面是“JavaScript中的Primitive对象封装介绍”的完整攻略。 什么是Primitive对象 JavaScript中存在两种数据类型:原始数据类型和引用数据类型。其中原始数据类型又称为Primitive类型,包括Number、String、Boolean、Null、Undefined和Symbol(ES6新增)。 Primitive对象是Jav…

    JavaScript 2023年5月27日
    00
  • javascript 人物逼真行走,已完成

    下面是详细讲解”javascript 人物逼真行走,已完成”的完整攻略。 简介 本攻略旨在讲解如何通过JavaScript实现人物逼真行走的效果。该效果主要通过CSS动画实现,同时使用JavaScript控制CSS动画完成人物行走的过程。 步骤 1. 准备人物图片 首先,我们需要准备好用于展示人物行走的图片。这些图片可以是人物行走各个姿势的连续帧,例如人物从…

    JavaScript 2023年5月28日
    00
  • jQuery EasyUI提交表单验证

    jQuery EasyUI 是一款非常流行的 jQuery 插件集合,其中包含了许多实用的 UI 组件,方便我们在 Web 开发中使用。其提交表单验证功能也非常实用,在本篇文章中,我们将详细讲解 jQuery EasyUI 提交表单验证的完整攻略,包括如何配置和使用验证器,以及如何处理验证结果。 准备工作 首先,我们需要引入 jQuery EasyUI 插件…

    JavaScript 2023年6月10日
    00
  • 深入探究使JavaScript动画流畅的一些方法

    我们来深入探究一下如何使JavaScript动画流畅。在此之前,我们需要了解为什么JavaScript动画往往会不够流畅。 为什么JavaScript动画不流畅? JavaScript的单线程执行机制 JavaScript是一门单线程语言,也就是说在执行JavaScript代码的时候,如果其中有一段代码耗时过长,那么后续代码会被阻塞。而大多数的动画效果都需要…

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