首页 > 其他分享 >AJAX-事件循环(超详细过程)

AJAX-事件循环(超详细过程)

时间:2023-11-02 21:32:30浏览次数:33  
标签:调用 console 队列 代码 AJAX 任务 循环 详细 执行

一.概念

JS有一个基于事件循环的并发模型,事件循环负责执行代码、收集和处理事件以及执行队列中的子任务

定义:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫时间循环。

原因:JS是単线程,为了让耗时的代码不阻塞其他代码运行,设计了事件循环模型

二、事件循环-执行过程

AJAX-事件循环(超详细过程)_任务队列

注意:浏览器多线程,JS才是单线程

详细例子说明(超详细)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>事件循环</title>
</head>

<body>

  <script>
    /**
     * 目标:阅读并回答执行的顺序结果
    */
    console.log(1)
    setTimeout(() => {
      console.log(2)
    }, 0)
    console.log(3)
    setTimeout(() => {
      console.log(4)
    }, 2000)
    console.log(5)

  </script>
</body>

</html>

AJAX-事件循环(超详细过程)_任务队列_02

第一行代码,是同步代码,放入调用栈里面立即执行,控制台打印:1,执行完以后立马出栈

AJAX-事件循环(超详细过程)_回调函数_03

第二行代码是一个异步代码,放入宿主环境,宿主环境发现是一个零秒的计时器,立马把这段代码推入任务队列当中,所以控制台此时并没有打印2,因为它此时在任务队列当中排队。

AJAX-事件循环(超详细过程)_调用栈_04

第三段代码,是一个同步代码,放入调用栈里立即执行,控制台打印3,并出栈。

AJAX-事件循环(超详细过程)_回调函数_05

第四段代码是异步代码,放入宿主环境里面等待2秒,在这2秒当中JS引擎会继续往下执行代码,由于第五段代码是同步代码,所以放入调用栈里面立即执行,控制台打印5,然后立马出栈。

AJAX-事件循环(超详细过程)_回调函数_06

当调用栈是空闲的时候,它会一直反复的尝试到任务队列里面调用要执行的回调函数

AJAX-事件循环(超详细过程)_调用栈_07

推入调用栈以后,立马执行该代码,打印2,然后出栈。

AJAX-事件循环(超详细过程)_回调函数_08

当宿主环境里的2秒过去以后,立马推入任务队列

AJAX-事件循环(超详细过程)_调用栈_09

此时调用栈处于空闲状态,到任务队列里面调用要执行的回调函数,推入到调用栈以后,立马执行,控制台打印4,然后出栈

上面是我们手工结果,我们运行代码看看结果是不是这样

AJAX-事件循环(超详细过程)_回调函数_10

结果正确!

三、宏任务与微任务

1.介绍

ES6之后引入了Promise对象,让JS引擎也可以发起异步任务

异步任务分为:

宏任务:由浏览器环境执行的异步代码

微任务:由JS引擎环境执行的异步代码

2.宏任务与微任务的代码

宏任务:

AJAX-事件循环(超详细过程)_回调函数_11

微任务:

AJAX-事件循环(超详细过程)_回调函数_12

注意:Promise本身是同步的,而then和catch回调函数是异步的

3.详细例子说明(超详细)

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>微任务与宏任务</title>
</head>

<body>
  <script>
    /**
     * 目标:阅读并回答打印的执行顺序
    */
    console.log(1)
    setTimeout(() => {
      console.log(2)
    }, 0)
    const p = new Promise((resolve, reject) => {
      console.log(3)
      resolve(4)
    })
    p.then(result => {
      console.log(result)
    })
    console.log(5)
  </script>
</body>

</html>

AJAX-事件循环(超详细过程)_调用栈_13

第一段是同步代码,放入调用栈中直接打印1,然后出栈

AJAX-事件循环(超详细过程)_回调函数_14

第二段是异步代码,放入宿主环境中,因为是0秒倒计时,且是宏任务,所以放入宏任务队列当中

AJAX-事件循环(超详细过程)_回调函数_15

第三段代码是同步代码,放入调用栈中理解执行,控制台打印3,resolve(4)是标记Promise处于成功状态

AJAX-事件循环(超详细过程)_回调函数_16

第四段代码p.then是同步的放入调用栈中,里面的回调函数是异步代码,且是微任务,所以放入微任务队列中

AJAX-事件循环(超详细过程)_回调函数_17

第五段代码是同步代码,放入调用栈中立即执行,控制台打印5,然后出栈

AJAX-事件循环(超详细过程)_回调函数_18

AJAX-事件循环(超详细过程)_调用栈_19

此时所有的同步代码都已执行完成,调用栈空闲,会反复的尝试到任务队列里面调用要执行的回调函数,由于微任务更接近JS引擎,所以优先调用微任务队列里面的回调函数,然后在调用栈里理解执行,控制台打印4,然后出栈

AJAX-事件循环(超详细过程)_任务队列_20

AJAX-事件循环(超详细过程)_回调函数_21

由于微任务队列已经清空了,所以开始调用宏任务里的回调函数(必须先清空微任务队列里的回调函数),然后在调用栈里立即执行打印2,然后出栈

让我们看看执行的结果是不是这样

AJAX-事件循环(超详细过程)_任务队列_22

对啦!

四、总结

AJAX-事件循环(超详细过程)_任务队列_23

当然还有我们的模型图

AJAX-事件循环(超详细过程)_调用栈_24

AJAX-事件循环(超详细过程)_回调函数_25

AJAX-事件循环(超详细过程)_回调函数_26





标签:调用,console,队列,代码,AJAX,任务,循环,详细,执行
From: https://blog.51cto.com/u_15858858/8154927

相关文章

  • do-while循环
    do-while循环其实很简单,只在while循环的基础做了些许改变。一般格式:do{<循环体语句>}while(<循环条件>);下面是do-while循环的流程图:在进入循环的时候不做判断,而是在执行完一轮循环体的代码之后,再来检查检查循环的条条件是否满足,如果满足则进行下一轮循环,不满......
  • JavaScript 将大数组拆分成多个小数组 循环调用接口
    项目需求:数据列表批量选择提交购物车,一次性提交数据量过大接口会报错,传递的参数是选中数据id的数组。项目运行很久了不做大改动,将提交数据总数限制在2000条以内,每500条走一次接口。思路:1.写一个将大数组拆分多个小数组的方法,arr为大数组,len为要拆分的小数组长度arrGroup(arr,......
  • python tkinter事件循环中一直检测初始化加载文件有没有加载成功
     pythontkinter事件循环中一直检测初始化加载文件有没有加载成功importtkinterastkdefcheck_file_loaded():#检查文件是否加载成功的逻辑iffile_loaded:#文件加载成功,执行相应操作print("文件加载成功")else:#文件未加......
  • sql server 截断和收缩所有用户数据库日志--用游标循环所有正常状态的用户数据库
    在服务器运维活动中,我们经常需要做一项工具就是将好多年的用户数据库日志文件截断并收缩为最小,以节省大量的磁盘空间。当数据库只有一两个时可以手动操作,但数据库数量众多时,就需要采用sql脚本,批量化执行这个过程。本人写了一段这样的脚本。并且经过验证执行无误。现在分享出来,您......
  • Ubuntu 一直卡在开机界面或者用户登录界面死循环问题的解决
    此方法并不全部通用,根据自己实际情况建议提前快照再试试此方法原因:NVIDIA驱动所致,之前安装方式nvidia驱动出问题。解决办法:卸载nvidia驱动,重新安装。(1)进入文本模式:CTRL+ALT+F1或者进入高级选项(按住esc或shift)(2)Uninstallanypreviousdrivers:sudoapt-getremovenvidia......
  • 循环神经网络 —— LSTM 有状态模型(stateful LSTM)和无状态模型(stateless LSTM)
    相关参考:训练后的LSTM模型在进行预测时的初始h_n和c_n是什么或应该怎么设置?   Keras中对RNN网络的statefull和stateless设置:链接:https://keras.io/zh/getting-started/faq/#how-can-i-use-stateful-rnns   =============================================== ......
  • Python循环数组的方法
    Python的遍历数组的三种方式。遍历方式假设:nums=[4,5,6,10,1]第一种,forin的语法,这种语法很方便,但是在写Python算法里面用到的少fornuminnums:print(num)第二种是下标访问,range生成0到数组最大长度的下标数组forindexinrange(len(nums)):print(index,nu......
  • Ajax + java Servlet 制作Web进度条
     运行效果图  index2.jsp <%@pagelanguage="java"pageEncoding="UTF-8"%><!DOCTYPEHTMLPUBLIC"-//W3C//DTDHTML4.01Transitional//EN"><html><head><scripttype="text/javascript"langua......
  • php: ajax请求,在返回信息前面出现ufeff红点,导致解析错误
    问题:ajax请求,在返回信息前面出现ufeff红点,导致解析错误原因:PHP文件格式编码位utf-8bom  文件编码是含BOM的会导致出现这种情况解决:  第一种方法:PHP文件格式编码转化为utf-8  第二种方法:在接口echo输出前面,添加一个ob_clean()函数           ......
  • 无法加载文件 E:\nodejs\node_global\npm.ps1,因为在此系统上禁止运行脚本。有关详
    npminstall报错解决办法打卡windospowershell并且以管理员运行输入命令set-executionpolicyremotesignedY......