JS中的异步编程与Promise

news/2025/3/16 9:24:15/

一、JavaScript的异步编步机制
在了解JavaScript的异步机制之前,我们首先需要理解JavaScript是一种单线程语言。单线程就意味着所有的任务需要按照顺序一次执行,如果前一个任务没有完成,后一个任务就无法开始。这个特性在执行大量或耗时任务时可能会导致阻塞或者界面卡死,这显然是不可取的。

为了解决这个问题,JavaScript引入了异步编程的机制。简单地说,异步就是你现在发出了一个“命令”,但是并不等待这个“命令”完成,而是继续执行下一个“命令”。只有在“听到”之前的那个“命令”完成了的消息时,才会回过头来处理这个“命令”的结果。这就是所谓的异步编程。

二、事件循环(Event Loop)和任务队列(Task Queue)
这种异步的机制是如何实现的呢?关键在于事件循环(Event Loop)和任务队列(Task Queue)。

事件循环是 JavaScript 内部的一个处理过程,系统会在此处不断地循环等待,检查任务队列中是否有任务,如果有,就处理它。

而任务队列,就是一个存储待处理任务的队列,当我们使用 setTimeout、setInterval、ajax等API时,实际上是向任务队列中添加了一个任务。

当主线程空闲时(也就是同步任务都执行完毕),便会去看任务队列里有没有任务,如果有,便将其取出执行;没有的话,则继续等待。

这个模型可以简单地用下面的代码表示:

while (true) {let task = taskQueue.pop();execute(task);
}

三、宏任务和微任务
在任务队列中,任务被分为两类:宏任务(MacroTask)和微任务(MicroTask)。两者的区别在于,宏任务在下一轮事件循环开始时执行,微任务在本轮事件循环结束时执行。这意味着微任务的优先级高于宏任务。

常见的宏任务有:script全文(可以看作一种宏任务)、setTimeout、setInterval、setImmediate(Node.js 环境)、I/O、UI渲染。

常见的微任务有:Promise、process.nextTick(Node.js环境)、MutationObserver(html5新特性)。

事件循环的顺序,决定了 JavaScript 代码的执行顺序。过程如下:

执行同步代码,这属于宏任务
执行栈为空,查询是否有微任务需要执行
执行所有微任务
必要的话渲染UI
然后开始下一轮 Event loop,执行宏任务中的异步代码
 

console.log('script start');  // 宏任务setTimeout(function() {console.log('setTimeout');  // 宏任务
}, 0);Promise.resolve().then(function() {console.log('promise1');    // 微任务
}).then(function() {console.log('promise2');    // 微任务
});console.log('script end');    // 宏任务


输出顺序为:script start -> script end -> promise1 -> promise2 -> setTimeout。这是因为JavaScript执行机制决定了微任务比宏任务优先执行。

四、requestAnimationFrame
requestAnimationFrame是一个优化动画效果的函数,也有它在事件循环中的位置。

requestAnimationFrame 的调用是有频率限制的,在大多数浏览器里,这个频率是60Hz,也就是说,每一次刷新间隔为1000/60≈16.7ms。requestAnimationFrame 的执行时机是在下一次重绘之前,而不是立即执行。

requestAnimationFrame 的优点是由系统来决定回调函数的执行时机。如果系统忙到一定程度,可能会两次“刷新”之间多次执行回调函数,这时就可以省略掉一些回调函数的执行。这种机制可以有效节省 CPU 开销,提高系统的性能。

requestAnimationFrame 的位置在事件循环中的具体位置是视浏览器的实现而定,但一般来说,它在宏任务执行完,渲染之前,这使得其可以获取到最新的布局和样式信息。

五、Promise的发展
Promise 对象代表一个异步操作的最终完成(或失败)及其结果值。一个 Promise 处于以下状态之一:

pending: 初始状态,既不是成功,也不是失败状态。
fulfilled: 意味着操作成功完成。
rejected: 意味着操作失败。
一个 promise 必须处于一种状态:fulfilled、rejected 或 pending。一个 promise 的状态在 settle 之后就不能再改变。

Promise起初是由社区提出并实现的,最早的版本是由 Kris Kowal 提出的 Q 库,后来被 ES6 正式接受,并成为了浏览器的原生对象。

Promise 主要解决了两类问题:

异步操作的一致性问题:无论异步操作是同步完成还是异步完成,使用 Promise 对象的 then 方法都可以以同样的方式进行处理。
回调地狱问题:回调地狱指的是多层嵌套的回调函数,导致代码难以维护和理解。Promise 可以通过链式调用的方式,解决回调地狱问题。
我们可以通过下面的代码示例来看一下 Promise 是如何工作的:
 

let promise = new Promise(function(resolve, reject) {// 异步处理// 处理结束后、调用resolve 或 reject
});promise.then(function(value) {// success
}, function(error) {// failure
});


Promise 的状态一旦改变,就会一直保持那个状态,不会再次改变。这个特性可以让我们有序地处理异步操作的结果,避免出现复杂的状态判断。
 

文章来源:https://blog.csdn.net/2301_79265530/article/details/134849326
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ppmy.cn/news/1262408.html

相关文章

MySQL数据库从小白到入门(二)

多表关系: 项目开发中,在进行数据库表结构设计时,会根据业务需求及业务模块之间的关系,分析并设计表结构。由于业务之间相互关联,所以各个表结构之间也存在着各种联系,基本上分为三种。 外键: 创…

【广州华锐互动VRAR】VR戒毒科普宣传系统有效提高戒毒成功率

随着科技的不断发展,虚拟现实(VR)技术已经逐渐渗透到各个领域,为人们的生活带来了前所未有的便利。在教育科普领域,VR技术的应用也日益广泛,本文将详细介绍广州华锐互动开发的VR戒毒科普宣传系统&#xff0…

macOS Big Sur/Mac电脑安装vscode显示您没有权限来打开应用程序‘Visual Studio Code‘ 请联系您的电脑或网络管理员问题修复

错误方法 首先我以为我的权限不足。,需要去用户群组里设置。结果根本不是这个的问题。 1.在系统偏好设置->用户与群组检查了一下我的用户是不是管理员 结果发现是管理员 2.根据苹果提示,右键我的文件夹->显示简介->最下面的共享与权限 解锁&…

2.6 A 的 LU 分解

一、A LU 线性代数很多关键的概念实际上就是矩阵的分解(factorization)。原始矩阵 A A A 变成两个或三个特殊矩阵的乘积。第一个分解,实际上也是最重要的分解,来自消元法。因子 L L L 和 U U U 都是三角形矩阵,分…

1 接口测试介绍

在软件测试工作中,接口测试是必不可少的。接口测试一般是发生在单元测试之后,系统测试之前。当开发人员输出API文档后,测试人员就可以开始编写接口测试用例了。接口测试可以让测试人员更早的介入,不需要等待前后端联调完成才开始测…

【ArcGIS Pro微课1000例】0053:基于SQL Server创建与启用地理数据库

之前的文章有讲述基于SQL Server创建企业级地理数据库,本文讲述在SQL Server中创建常规的关心数据库,然后在ArcGIS Pro中将其启用,转换为企业级地理数据库。 1. 在SQL Server中创建数据库** 打开SQL Server 2019,连接到数据库服务器。 展开数据库连接,在数据库上右键→新…

MQTT协议对比QUIC网络性能测试模拟弱网测试

MQTT正常外网压测数据---时延diff/ms如下图: MQTT弱网外网压测数据 QUIC正常外网压测数据 QUIC弱网外网压测数据 结论: 在弱网情况下,MQTT和QUIC(Quick UDP Internet Connections)这两种协议的网络性能表现也会有…

表单小程序作用体现在哪

表单的用途非常广泛,它是线上收集信息或用户预约/需求服务的重要方式,对商家来说如今线上平台非常多,生意开展的形式也越来越多,比如常见的预约、报名、收款、产品支付等都可以通过表单实现。 接下来啊让我们看看通过【雨科】平台…