简单聊聊JavaScript中的事件循环

yizhihongxing

我们来谈谈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 获取本地文件及目录的方法(推荐)

    当我们需要在JavaScript中获取本地文件或目录时,可以通过File API实现。File API是一组用于读取本地文件的JavaScript接口。 下面是使用File API获取本地文件及目录的步骤: 1. 创建一个input元素 <input type="file" id="input-element"&…

    JavaScript 2023年5月27日
    00
  • 通过原生JS实现为元素添加事件的方法

    通过原生JS为元素添加事件可以使用 addEventListener() 方法。以下是实现为元素添加点击事件的步骤: 获取需要添加事件的元素 首先需要获取需要添加事件的元素,可以使用 document.getElementById() 方法获取元素的引用,也可以使用 document.querySelector() 方法获取元素的引用,具体使用哪一种方法取决…

    JavaScript 2023年6月10日
    00
  • JS及JQuery对Html内容编码,Html转义

    JS及JQuery对Html内容编码,Html转义是为了防止用户提交的数据中包含恶意代码,而对HTML标签中的一些字符进行转义的过程。下面我将分别对JS和JQuery方式进行详细讲解。 1. JS对Html内容编码 在JS中,可以使用 encodeURI 函数来对Url编码,使用encodeURIComponent函数对Url参数进行编码, 使用escape…

    JavaScript 2023年5月19日
    00
  • 浅谈js数组和splice的用法

    浅谈js数组和splice的用法 在JavaScript中,数组是一种非常常见的数据类型。而splice()方法则是JavaScript数组提供的一种很有用的方法,用来对数组进行删除、添加、替换等操作。本文将会为你详细讲解js数组和splice的用法,深入了解数组和splice的使用可以使你的JavaScript编程达到更高的层次。 数组 数组是一种非常重要…

    JavaScript 2023年5月27日
    00
  • 基于javascript的异步编程实例详解

    基于 JavaScript 的异步编程实例详解 在 JavaScript 中,由于事件循环机制,异步编程已经成为了常态。在本文中,我们将深入讲解基于 JavaScript 的异步编程实例的完整攻略。我们会通过两条示例来说明异步编程的原理和实现。 示例1:使用Callback函数实现异步编程 在 JavaScript 中,回调函数是实现异步编程的常用方式。在示…

    JavaScript 2023年5月28日
    00
  • 新手入门带你学习JavaScript引擎运行原理

    新手入门带你学习JavaScript引擎运行原理 1. 前言 JavaScript语言已经成为web前端技术的必备语言之一,对于想进一步掌握JavaScript运行原理的同学,了解JavaScript引擎的运行机制是非常重要的。 本文将从以下几个方面进行介绍: JavaScript引擎的功能和作用 JavaScript引擎的基本原理 实战案例学习 2. Ja…

    JavaScript 2023年5月27日
    00
  • javascript页面上使用动态时间具体实现

    我们来详细讲解一下Javascript页面上使用动态时间的具体实现。 一、实现方法 1.使用setInterval()方法实现动态时间 Javascript可以通过setInterval()方法,每隔一定时间执行一段代码,源码如下: setInterval(function(){ // 在此处执行需要执行的代码 }, 时间间隔); 其中,第一个参数是需要每隔…

    JavaScript 2023年5月27日
    00
  • 2021年值得向Python开发者推荐的VS Code扩展插件

    下面是详细讲解“2021年值得向Python开发者推荐的VS Code扩展插件”的完整攻略。 1. 简介 VS Code 是一款免费开源的轻量级编辑器,支持多种编程语言,Python 是其中之一。丰富的扩展插件使得 VS Code 更加强大,可以让开发者更加高效地编写 Python 代码。本攻略将介绍一些值得向 Python 开发者推荐的扩展插件。 2. 推…

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