当前位置: 首页 > news >正文

async/await 函数

1. async函数的原理

async函数在本质上是基于Promise实现的,所以先要理解promise和JavaScript 异步操作

JavaScript 异步操作:

JavaScript 是单线程的,它通过 事件循环(Event Loop) 来处理异步操作。通常,异步操作不会阻塞主线程,而是通过将回调函数放入事件队列来等待执行。这种机制使得 JavaScript 能够同时处理多个任务,而不会阻塞 UI 或其他操作。

Promise 的工作原理

Promise 是一种表示异步操作最终完成或失败的机制。它有三种状态:

  • Pending:初始状态,表示操作尚未完成。
  • Resolved/Fulfilled:表示操作完成并返回了成功的结果。
  • Rejected:表示操作失败并返回了错误。

Promise 的常见用法是通过 .then().catch() 来处理异步操作的结果:

fetch('https://api.example.com/data').then(response => response.json()).then(data => console.log(data)).catch(error => console.error(error));

Promise之所以可以解决回调地狱就是因为promise是个对象,而他的回调函数是附加在promise上的,所以遇到回调地狱问题我们就可以用promise链式调用来解决它,它可以从回调函数的层层包含中跳出来

async/await 是在 Promise 的基础上简化了异步编程的工具。

async 函数本质上是返回一个 Promise 的函数,即使你没有显式地返回 Promise,它也会自动将函数的返回值封装为一个 Promise。这使得异步函数看起来更像同步代码,减少了传统异步操作中对 .then() 的需求。当一个函数被声明为 async 时,内部会自动有一个隐式的 Promise

async function example() {return "Hello, World!";
}example().then(result => console.log(result));  // "Hello, World!"

await

await 操作符用于等待一个 Promise 兑现并获取它兑现之后的值。它只能在异步函数或者模块顶层中使用。当他后面跟着promise对象的时候,他会暂停异步代码等待promise执行完然后返回其兑现的值,如果是一个非promise,那么就会把它当作是已经兑现的Promis,正常执行,如果promise被拒绝,返回被拒绝的原因。

function resolveAfter2Seconds(x) {return new Promise((resolve) => {setTimeout(() => {resolve(x);}, 2000);});
}async function f1() {let x = await resolveAfter2Seconds(10);console.log(x); // 10
}f1();

当函数执行到 await 时,被等待的表达式会立即执行,所有依赖该表达式的值的代码会被暂停,并推送进微任务队列(microtask queue)。然后主线程被释放出来,用于事件循环中的下一个任务。即使等待的值是已经敲定的 promise 或不是 promise,也会发生这种情况

以下示例代码来自mdn

async function foo(name) {console.log(name, "start");await console.log(name, "middle");console.log(name, "end");
}foo("First");
foo("Second");// First start
// First middle
// Second start
// Second middle
// First end
// Second end

用promise写相当于

function foo(name) {return new Promise((resolve) => {console.log(name, "start");resolve(console.log(name, "middle"));}).then(() => {console.log(name, "end");});
}

http://www.dtcms.com/a/291818.html

相关文章:

  • 【CVPR 2025】低光增强RT-X Net( 红外辅助结构引导)--part1论文精读
  • 开发者的AI认知指南:用大模型重新理解人工智能(下)
  • 公交车客流人数统计管理解决方案:智能化技术与高效运营实践
  • 九鼎X8390 开发板 联发科 MT8390 / MT8370 芯片平台
  • 华为高斯Gauss数据库版本与兼容协议--详解(附带Gorm连接示例代码)
  • 5G工业路由器如何凭借高性价比助力多行业数字化转型?
  • 2025 LCP用2,6酸市场前瞻:全面洞察与投资潜力预测
  • iOS组件化详解
  • Windows 环境下,使用 VirtualBox 安装 Ubuntu 虚拟机
  • 34、鸿蒙Harmony Next开发:使用动画-转场动画
  • JMeter groovy 编译成.jar 文件
  • RabbitMQ--批量处理
  • 【Zephyr开发实践系列】09_LittleFs文件系统操作
  • 在easyui中如何自定义表格里面的内容
  • 目标检测系列(六)labelstudio实现自动化标注
  • vue2 webpack 部署二级目录、根目录nginx配置及打包配置调整
  • 容器化部署 Tomcat + MySQL 实战指南:从入门到进阶
  • MongoDB数据库详解-针对大型分布式项目采用的原因以及基础原理和发展-卓伊凡|贝贝|莉莉
  • 架构演进核心路线:从离线仓库到实时湖仓一体
  • LLM评测框架Ragas Agents or Tool Use Cases指标(解决了Ollama推理框架不支持的问题)
  • 微软徽标认证是什么?如何快速获取驱动签名?
  • Linux操作系统从入门到实战(十二)Linux操作系统第一个程序(进度条)
  • 【用户管理】usermod设置主组和附加组(三)
  • es搜索实现既能模糊查询又能分词查询
  • [Dify] -进阶10- Dify 的用户输入结构:变量、参数、文件上传全解析
  • stm32 智能小车
  • 【多线程篇22】:ConcurrentHashMap的并发安全原理剖析
  • 低成本、高泛化能力的无人机自主飞行!VLM-Nav:基于单目视觉与视觉语言模型的无地图无人机导航
  • C++类和对象(3)
  • 从零搭建 OpenCV 项目(新手向)--第一天初识OpenCV与图像基础