iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >JavaScript事件循环实例分析
  • 588
分享到

JavaScript事件循环实例分析

2023-07-02 08:07:15 588人浏览 八月长安
摘要

这篇文章主要讲解了“javascript事件循环实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript事件循环实例分析”吧!前言异步函数也是有执行顺序的。本质上来说,Ja

这篇文章主要讲解了“javascript事件循环实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript事件循环实例分析”吧!

前言

异步函数也是有执行顺序的。本质上来说,JavaScript是单线程语言,不管是在浏览器中还是nodejs环境下。浏览器在执行js代码和渲染DOM节点都是在同一个线程中,执行js代码就无法渲染DOM,渲染DOM的时候就无法执行js代码。如果按照这种同步方式执行,页面的渲染将会出现白屏甚至是报错,特别是遇到一些耗时比较长的网络请求或者js代码,因此在实际开发中一般是通过异步的方式解决。

什么是异步?js是一步一步执行代码的,遇到alert这种阻塞代码时,js将会停止往下执行直到阻塞代码执行完毕。异步就是将函数放在单独的异步队列中,不会产生阻塞,js可以继续往下执行,等到同步代码执行完毕后再执行异步队列中的函数。因此,js会先执行完同步代码,才会执行异步代码。异步函数之间,虽然都是异步,但是还是有相对的执行顺序。

异步函数的执行主要依靠事件循环来处理,本文重点探讨异步的分类(宏任务、微任务)、事件循环以及异步函数的执行顺序。

宏任务

宏任务,也可简单的说成是任务,在下一轮DOM渲染之后执行。常见的宏任务有:

  • setTimeout:设置一个定时器,该定时器会在设置的延迟时间到期后执行一个函数或者指定的代码块。值得注意的是,setTimeout不一定会在延迟时间到达后就立即执行函数,而是会判断执行队列中是否还有函数没有处理,如果没有了并且栈为空,setTimeout才会在延迟时间到达后执行函数。

    // setTimeout 延迟执行不等于到期时立即执行let now = new Date().getSeconds();setTimeout(() => {    console.log('this is setTimeout 0');}, 0);setTimeout(() => {    console.log('this is setTimeout 200');}, 200);while(true) {    if (new Date().getSeconds() - now >= 2) {        console.log('break out while loop');        break;    }}

    运行结果

  • break out while loop
    this is setTimeout 0
    this is setTimeout 200

    先执行同步代码,再执行异步。setTimeout(() => {}, 0)表示0毫秒后立即执行函数,但是当前执行队列中还有未处理完的while循环,因此需要等到while循环执行完毕后,才会根据延迟到期时间执行函数。

  • setInterval:设置定时器,表示在固定的时间间隔内,重复执行某一函数或者特定的代码块。注意使用setInterval有最小延迟时间限制以及确保执行时间要小于间隔时间,如果执行时间无法确定,则应采用递归调用setTimeout的方式代替。

  • 网络请求:只要是指XMLHttpRequest等网络请求

微任务

微任务,在下一轮DOM渲染之前执行,微任务比宏任务更早执。常见的微任务有:

  • promise:表示一个异步操作最终的结果和返回值,可能会失败,也可能成功。异步函数在执行时,什么时候返回结果是不可预料的,Promise把异步操作的返回值和函数关联起来,保证在异步执行结束后会执行对应的函数,并通过函数返回操作值。这种效果就类似于把异步代码“同步执行”。

  • queueMicrotask:将函数添加到微任务队

console.log('start');// 微任务队列Promise.resolve().then(() => {    console.log('promise then');});queueMicrotask(() => {    console.log('queueMicrotask');});console.log('end');

运行结果

start
end
promise then
queueMicrotask

事件循环

因为有异步操作的存在,所以出现了事件循环,如果都是同步操作,一行一行执行代码,事件循环也就失去了用武之地。在了解事件循环前,还需要补充js的执行过程:

JavaScript事件循环实例分析

js在执行代码时,遇到函数就会将其添加到调用栈中,每一帧都会存储当前函数的参数和局部变量,当一个函数执行完毕,则会从调用栈中弹出,直到栈被清空,那么程序也就执行完毕。在执行的过程中,需要的引用数据都是从堆中获取。

在实际开发中,往往是同步代码和异步代码都有。在js执行时,还是从第一行代码开始执行,遇到函数就将其添加到栈中,然后执行同步操作;如果遇到异步函数,则根据其类型,宏任务就添加到宏任务队列,微任务添加到微任务队列。直到同步代码执行完毕,则开始执行异步操作。

异步操作后于同步操作,异步操作内部也是分先后顺序的。总的来说:

  • 微任务先于宏任务执行

  • 微任务与微任务之间根据先后顺序执行,宏任务与宏任务之间根据延迟时间顺序执行

  • 微任务在下一轮DOM渲染前执行,宏任务在下一轮DOM渲染之后执行

  • 每个任务的执行都是一次出栈操作,直到栈被清空

微任务比宏任务先执行

console.log('start');// 宏任务队列setTimeout(() => {    console.log('setTimeout');});// 微任务队列Promise.resolve().then(() => {    console.log('promise then');});console.log('end');// 执行结果startendpromise thensetTimeout

微任务在下一轮DOM渲染前执行,宏任务在之后执行

let div = document.createElement('div');div.innerhtml = 'hello world';document.body.appendChild(div);let divList = document.getElementByTagName('div');console.log('同步任务 length ---', list.length);console.log('start');setTimeout(() => {    console.log('setTimeout length ---', list.length);    alert('宏任务 setTimeout 阻塞'); // 使用alert阻塞js执行});Promise.resolve().then(() => {    console.log('promise then length ---', list.length);    alert('微任务 promise then 阻塞);});console.log('end');

事件循环

event loop会持续监听是否有异步操作,如果有则添加到对应的队列中,等待执行。例如在宏任务中添加微任务,或者在微任务中添加宏任务,当前任务执行完后,可能还会有新的任务添加到事件循环中。

JavaScript事件循环实例分析

宏任务与微任务

  • 微任务中创建宏任务

        new Promise((resolve) => {      console.log('promise 1');      setTimeout(() => {        console.log('setTimeout 1');      }, 500);      resolve();    }).then(() => {      console.log('promise then');      setTimeout(() => {        console.log('setTimeout 2');      }, 0);    });    new Promise((resolve) => {      console.log('promise 2');      resolve();    })

    运行结果

  • promise 1
    promise 2
    promise then
    setTimeout 2
    setTimeout 1

    解析

    js执行代码,遇到两个Promise,则分别添加到微任务队列,同步代码执行完毕。

    在微任务队列中根据先进先出,第一个Promise先执行,遇到setTimeout,则添加到宏任务队列,resolve()返回执行结果并执行then,事件循环将其继续添加到微任务队列;第一个Promise执行完毕,执行第二个Promise。

    继续执行微任务队列,直到清空队列。遇到setTimeout,并将其添加到宏任务队列

    宏任务队列现在有两个任务待执行,由于第二个setTimeout的延迟事件更小,则优先执行第二个;如果相等,则按照顺序执行。

    继续执行宏任务队列,直到清空队列。

  • 宏任务中创建微任务

        setTimeout(() => {      console.log('setTimeout 1');      new Promise((resolve) => {        console.log('promise 1');        resolve();      }).then(() => {        console.log('promise then');      })    }, 500);    setTimeout(() => {      console.log('setTimeout 2');      new Promise((resolve) => {        console.log('promise 2');        resolve();      })    }, 0);

    运行结果

  • setTimeout 2
    promise 2
    setTimeout 1
    promise 1
    promise then

    解析

    js执行代码,遇到两个setTimeout,将其添加到宏任务队列,同步代码执行完毕

    先检查微任务队列中是否有待处理的,刚开始肯定没有,因此直接执行宏任务队列中的任务。第二个为零延迟,需要优先执行。遇到Promise,将其添加到微任务队列。第一个宏任务执行完毕

    在执行第二个宏任务时,微任务队列中已经存在待处理的,因此需要先执行微任务。

    微任务执行完毕,并且延迟时间到期,第一个setTimeout开始执行。遇到Promise,将其添加到微任务队列中

    执行微任务队列中的Promise,执行完毕后遇到then,则将其继续添加到微任务队列

    直到所有微任务执行完毕

  • 宏任务中创建宏任务

        setTimeout(() => {      console.log('setTimeout 1');      setTimeout(() => {        console.log('setTimeout 2');      }, 500);      setTimeout(() => {        console.log('setTimeout 3');      }, 500);      setTimeout(() => {        console.log('setTimeout 4');      }, 100);    }, 0);

    运行结果

  • setTimeout 1
    setTimeout 4
    setTimeout 2
    setTimeout 3

    解析

    宏任务中创建宏任务,执行顺序一般来说是按照先后顺序的。对于setTImeout来说,延迟时间相同,则按照先后顺序执行;延迟时间不同,则按照延迟时间的大小先后顺序执行

  • 微任务中创建微任务

        new Promise((resolve) => {      console.log('promise 1');      new Promise((resolve) => {        console.log('promise 2');        resolve();      });      new Promise((resolve) => {        console.log('promise 3');        resolve();      })      resolve();    })

    运行结果

  • promise 1
    promise 2
    promise 3

    解析

    微任务中创建微任务,执行顺序一般来说是按照先后顺序执行的。

感谢各位的阅读,以上就是“JavaScript事件循环实例分析”的内容了,经过本文的学习后,相信大家对JavaScript事件循环实例分析这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: JavaScript事件循环实例分析

本文链接: https://www.lsjlt.com/news/340546.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • JavaScript事件循环实例分析
    这篇文章主要讲解了“JavaScript事件循环实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“JavaScript事件循环实例分析”吧!前言异步函数也是有执行顺序的。本质上来说,Ja...
    99+
    2023-07-02
  • NodeJS事件循环实例分析
    这篇文章主要介绍“NodeJS事件循环实例分析”,在日常操作中,相信很多人在NodeJS事件循环实例分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”NodeJS事件循环实例分析”的疑惑有所帮助!接下来,请跟...
    99+
    2023-06-29
  • Javascript单线程和事件循环实例分析
    本篇内容介绍了“Javascript单线程和事件循环实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、单线程Javascript 是...
    99+
    2023-07-02
  • JavaScript之事件循环的示例分析
    这篇文章主要介绍JavaScript之事件循环的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!js中的事件循环因为JavaScript是单线程的,同一事件只能执行一种方法,所以会将程序中的方法加入到执行栈中按...
    99+
    2023-06-20
  • javascript事件循环event loop的示例分析
    小编给大家分享一下javascript事件循环event loop的示例分析,希望大家阅读完这篇文章之后都有所收获,下面让我们一起去探讨吧!具体如下:js是单线程的,但是event loop的出现,使得js...
    99+
    2024-04-02
  • Node.js事件循环实例代码分析
    本篇内容主要讲解“Node.js事件循环实例代码分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“Node.js事件循环实例代码分析”吧!通过代码模拟 eventloopconst e...
    99+
    2023-07-04
  • Node中的事件循环、process.nextTick()实例分析
    这篇文章主要讲解了“Node中的事件循环、process.nextTick()实例分析”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Node中的事件循环、p...
    99+
    2024-04-02
  • Node.js事件循环机制实例代码分析
    这篇文章主要介绍“Node.js事件循环机制实例代码分析”,在日常操作中,相信很多人在Node.js事件循环机制实例代码分析问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Node.js事件循环机制实例代码分析...
    99+
    2023-07-04
  • Node.js中的Buffer和事件循环实例分析
    这篇“Node.js中的Buffer和事件循环实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来...
    99+
    2024-04-02
  • Node.js中事件循环的示例分析
    这篇文章主要介绍Node.js中事件循环的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!Node 自身的执行模型——事件循环,正是它使得回调函数十分普遍。在进程启动时,Nod...
    99+
    2024-04-02
  • nodejs中事件和事件循环的示例分析
    这篇文章主要介绍nodejs中事件和事件循环的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!nodejs中的事件循环虽然nodejs是单线程的,但是nodejs可以将操作委托给系统内核,系统内核在后台处理这些...
    99+
    2023-06-14
  • JavaScript事件循环同步任务与异步任务实例分析
    本篇内容介绍了“JavaScript事件循环同步任务与异步任务实例分析”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!执行栈与任务队列执行栈姑...
    99+
    2023-07-02
  • JavaScript循环作用域实例分析
    本篇内容主要讲解“JavaScript循环作用域实例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“JavaScript循环作用域实例分析”吧! 循环作用域...
    99+
    2024-04-02
  • JavaScript循环的示例分析
    这篇文章主要介绍JavaScript循环的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!要计算1+2+3,我们可以直接写表达式:1 + 2 + 3; // 6要计算1+2+3...
    99+
    2024-04-02
  • JS中事件循环机制的示例分析
    小编给大家分享一下JS中事件循环机制的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!1、JavaScript是单线程的JavaScript 是一种单线程的...
    99+
    2023-06-29
  • JavaScript之事件循环案例讲解
    js中的事件循环 因为JavaScript是单线程的,同一事件只能执行一种方法,所以会将程序中的方法加入到执行栈中按照后进先出的顺序依次执行,当遇见异步任务时不会被阻塞,而是将任务放...
    99+
    2024-04-02
  • nodejs中事件循环机制的示例分析
    这篇文章主要介绍了nodejs中事件循环机制的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。前端开发离不开JavaScript,Javascript是一种web前端语...
    99+
    2023-06-14
  • 详解JavaScript事件循环
    目录一、事件循环的执行过程二、事件循环进阶用法三、JavaScript任务类型3.1 同步任务&异步任务3.2 宏任务&微任务JavaScript事件循环是一种机制,...
    99+
    2023-05-16
    JavaScript事件循环 JavaScript循环
  • JavaScript中怎么实现事件循环
    今天就跟大家聊聊有关JavaScript中怎么实现事件循环,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。1.Main.js 执行2.调用second...
    99+
    2024-04-02
  • JavaScript函数和事件实例分析
    今天小编给大家分享一下JavaScript函数和事件实例分析的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作