一篇文章让你搞清楚JavaScript事件循环

yizhihongxing

一篇文章让你搞清楚JavaScript事件循环

什么是事件循环?

JavaScript是一门单线程语言,它有一个主线程执行环境(即全局上下文环境),主线程会按照代码的顺序依次执行。然而,由于JavaScript需要处理UI操作、网络请求、定时器等事件,而这些事件需要等待的时间可能非常长,如果按照阻塞式的方式等待,就会影响用户体验。因此,JavaScript采用异步执行和事件循环机制来解决这个问题。

事件循环是一种执行模型,用于处理JavaScript中异步代码的执行顺序。JavaScript通过异步机制将带有回调函数的异步任务放在任务队列中,主线程开始执行同步任务,当同步任务结束后,JavaScript引擎开始轮询任务队列,如果任务队列中有待处理任务,就将它们推送到主线程中执行,主线程继续执行一遍事件循环后回到等待下一个任务的状态。这就是事件循环的基本流程。

任务队列

常见的任务队列主要有三个:主线程任务队列、微任务队列和宏任务队列。

主线程任务队列

主线程任务队列是一个FIFO队列,主要存储异步任务的回调函数。当主线程执行完当前的同步任务后,会检查主线程任务队列中是否有待处理的函数,如果有,那么主线程将会将这些任务加入到主线程任务队列的末尾,然后处理这些任务。

微任务队列

微任务队列是用于存储带有回调函数的异步任务,这些任务通常是由Promise.then()、请求动画帧和queueMicrotask()方法添加的。当JavaScript执行完所有同步任务和在主线程任务队列中发现了异步任务后,JavaScript引擎先会检查是否存在微任务队列。如果存在微任务,那么它们将会被依次处理,直到微任务队列为空为止。

宏任务队列

宏任务队列用于存放那些需要异步执行的回调函数。主线程任务队列中的回调函数通常会被添加到宏任务队列,此外,像setTimeout()、setInterval()和I/O操作等也会被添加到宏任务队列中。当主线程任务队列中的任务全部执行完毕并且微任务队列中所有任务也执行完毕后,JavaScript引擎会去检查宏任务队列,如果有宏任务,则将队列中的第一个任务加入到主线程任务队列中执行,如果宏任务队列为空,则继续等待新的宏任务的加入。

示例:setTimeout和Promise

接下来,我们使用两个示例来展示事件循环是如何工作的。

示例一:setTimeout

console.log('main1')
setTimeout(() => {
  console.log('timeout')
}, 0)
console.log('main2')

上面的代码会先输出‘main1’,接着输出‘main2’,最后输出‘timeout’。这是因为setTimeout()是一种宏任务,它会被添加到宏任务队列中等待执行,而当前任务队列中的两个console.log()函数是同步的,它们会在当前的任务队列被执行完毕后立即执行。当前任务队列执行完毕后,JavaScript引擎会检查宏任务队列中是否有待处理的任务,如果有,则将它们添加到主线程任务队列中执行。

所以,上面的代码输出的顺序是先输出同步任务中的‘main1’和‘main2’,然后由于setTimeout的回调函数处于宏任务队列中,所以在当前任务队列执行完毕后,JavaScript引擎会去宏任务队列中查找任务,由于宏任务队列中只有一个任务(setTimeout的回调函数),所以将它加入主线程任务队列中执行,在主线程任务队列中执行的时候才输出‘timeout’。

示例二:Promise

console.log('main1')
Promise.resolve().then(() => {
  console.log('promise')
})
console.log('main2')

上面的代码会先输出‘main1’,接着输出‘main2’,最后输出‘promise’。当前任务队列中的console.log()函数是同步的,它们会在当前的任务队列被执行完毕后立即执行,而Promise.resolve().then()方法是一种添加微任务的方式,它会将回调函数添加到微任务队列中等待执行,等整个当前任务队列执行完毕后,JavaScript引擎会去检查微任务队列中是否有待处理任务,如果有,则会依次执行这些微任务。

在上述代码中,当main2执行完毕后,JavaScript引擎会查找微任务队列,并发现存在微任务,然后依次执行微任务队列中的回调函数,于是输出‘promise’。

到此为止,我们已经基本了解了JavaScript事件循环的执行过程以及任务队列的相关概念和使用方法。在实际开发中,了解事件循环的执行过程能够帮助我们更好地理解异步编程模型,从而更好地掌握JavaScript的异步机制。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一篇文章让你搞清楚JavaScript事件循环 - Python技术站

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

相关文章

  • Electron vue的使用教程图文详解

    Electron Vue的使用教程图文详解 Electron Vue是一款基于Electron和Vue的框架,可以用于快速构建桌面应用。本文将详细讲解如何使用Electron Vue构建桌面应用程序。 前置条件 在开始使用Electron Vue之前,需要具备以下技能和工具: 基本的HTML、CSS和JavaScript技能 Vue.js的基础知识 Node…

    JavaScript 2023年6月11日
    00
  • javascript 使用sleep函数的常见方法详解

    让我来详细讲解一下 “javascript 使用sleep函数的常见方法详解” 的完整攻略。 什么是sleep函数? 在JavaScript中,本质上并没有自带的sleep函数。它是一种同步执行的函数,能够在程序执行到该函数时阻塞线程一段时间,然后再继续执行。 常见的sleep实现方法 在JavaScript中实现sleep函数的方法有很多,这里介绍两个常见…

    JavaScript 2023年5月27日
    00
  • vue播放flv、m3u8视频流(监控)的方法实例

    针对“vue播放flv、m3u8视频流(监控)的方法实例”,下面是完整的攻略。 一、前置知识 在开始操作前,需要确定以下知识: 熟悉vue.js框架 熟悉flv.js和hls.js这两个第三方库 二、flv.js播放flv视频流 flv.js是一个Flash视频文件格式播放器,支持原生HTML5技术和Adobe Flash技术。下面以播放flv视频流为例,介…

    JavaScript 2023年6月11日
    00
  • jQuery animate()实现背景色渐变效果的处理方法【使用jQuery.color.js插件】

    下面详细讲解如何使用jQuery的animate()方法实现背景色渐变效果,需要使用jQuery.color.js插件。具体步骤如下: 1. 引入jQuery和jQuery.color.js插件 在HTML文件中,我们需要引入jQuery和jQuery.color.js插件。 <script src="https://code.jquery.…

    JavaScript 2023年6月11日
    00
  • JavaScript实现显示函数调用堆栈的方法

    要实现显示函数调用堆栈的功能,可以使用JavaScript内置的Error对象的堆栈跟踪机制。具体实现步骤如下: 1. 创建Error对象 JavaScript中Error对象表示运行时错误,它包含一个message属性和一个stack跟踪堆栈信息的属性。因此,可以使用new关键字来创建一个Error对象。 function printStackTrace(…

    JavaScript 2023年6月11日
    00
  • JavaScript实现获取最近7天的日期的方法详解

    JavaScript实现获取最近7天的日期的方法详解 介绍 在Web前端开发中,获取最近7天的日期是很常见的需求。本文将提供几种实现方法,包括原生JavaScript和Moment.js库的使用方法。 实现方法一:原生JavaScript 方法一:获取当前日期并递减7天 通过使用Javascript内置的Date对象,我们可以获取现在的日期,并通过设定日期对…

    JavaScript 2023年5月27日
    00
  • 浅析Node.js实现HTTP文件下载

    浅析Node.js实现HTTP文件下载 在Node.js中,可以使用http模块实现HTTP文件下载。具体的步骤如下: 引入http模块和fs模块 javascript const http = require(‘http’); const fs = require(‘fs’); 创建一个HTTP GET请求 javascript const url = ‘…

    JavaScript 2023年5月28日
    00
  • javascript与java有什么关系(区别与相似)

    JavaScript和Java这两个词看起来很相似,但它们是两个完全不同的编程语言。在这篇文章中,我们将讨论JavaScript和Java之间的区别和相似之处。 区别 语法不同 JavaScript和Java有完全不同的语法。JavaScript语法更为简单,而Java则需要更多的代码和结构。JavaScript采用的是弱类型变量,因此在声明变量并定义其类型…

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