百度360必应搜狗淘宝本站头条
当前位置:网站首页 > IT知识 > 正文

还在用老旧的Promise?你该试试Async/Await了!

liuian 2025-03-25 15:21 28 浏览

async函数,也就是我们常说的async/await,是在ES8中引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法。async和await关键字让使用 Promises变得容易,而无需刻意地链式调用Promise。并且与嵌套的.then相比,代码可读性更好。下面就来介绍一下它的具体使用以及规则。

一、async函数

1. 用法

在函数声明的前面加上async关键字,就变成了 async 函数。

async function f() {

return 'hello world';

}

2. 返回值

async 函数的返回值是一个 Promise 实例,Promise 实例的结果由 async 函数的返回值决定:

如果返回的是一个 Promise 实例,最终得到的 Promise 对象的状态与值与返回的 Promise 实例保持一致。

如果返回的是一个非 Promise 实例的值,async 函数返回的一个状态为 resolved 的 Promise 实例,value 是函数内返回的值。

如果没有返回值,async 函数返回一个状态为resolved 的 Promise 实例,value 是undefined。

如果抛出错误,async 函数返回一个状态为 rejected 的 Promise 实例,reason 是抛出的错误。

二、await表达式

async function main(){

let result = await Promise.resolve('hello world');

console.log(result); // hello world

};

main();

async function f(){

let result = await 998;

console.log(result); // 998

}

f();

async function foo(){

let result = await {

then(resolve, reject){

setTimeout(() => {

resolve('success')

}, 2000);

}

};

console.log(result); // success

}

foo();

1. 规则

await 表达式必须写在 async 函数的里面。但async函数中可以没有 await,不过一般二者是一起使用的。

await 表达式可以取到 Promise 实例的结果(就是状态发生改变后传到回调函数的值)。当然,必须等到 Promise 实例的状态发生变化,await 表达式才能取到值。

2. 关于 await 的右侧的表达式

一般为 Promise 实例,await 表达式的值就是该 Promise 实例的结果。

如果是个其他类型的值(非 Promise 类型),await 表达式的值就是这个值。

后面是一个 thenable 对象(即定义then方法的对象),那么会将其等同于 Promise 对象。(介绍 Promise.resolve() 方法的时候介绍过 thenable 对象)。

3. 注意

如果 await 右侧是个状态为失败的 Promise 实例,会抛出异常。我们建议将 await 表达式放在try...catch结构里面。

async function f() {

try {

await Promise.reject('出错了');

} catch(e) {

}

return await Promise.resolve('hello world');

三、案例

使用async/await有诸多好处,这里例举一个前端最常用的东西(ajax发送请求)来直观的感受一下使用async/await带来的便捷之处。

1. 传统的Ajax请求

//创建异步对象

var xhr = new XMLHttpRequest();

//设置请求的url参数,参数一是请求的类型,参数二是请求的url,可以带参数,动态的传递参数starName到服务端

xhr.open('GET','http://www.atguigu.com');

//注册事件 onreadystatechange 状态改变就会调用

xhr.onreadystatechange = function () {

//如果能够进到这个判断 说明 数据 完美的回来了,并且请求的页面是存在的

if (xhr.readyState == 4 && xhr.status == 200) {

    console.log(ajax.responseText); //输出相应的内容

  }

}

//发送请求

ajax.send();

2. 用promise封装Ajax

使用promise可以更方便管理异步请求。promise可以用在单个或多个ajax请求,在多个请求当中可以指定请求的顺序。话不多说,上代码:

function sendAjax(url) {

let xhr = new XMLHttpRequest()

return new Promise(function (resolve, reject) {

xhr.open('GET', url)

xhr.onreadystatechange = function () {

if (xhr.readyState === 4) {

if (xhr.status === 200) {

resolve(xhr.responseText) // 成功执行 resolve

} else {

reject() // 失败执行 reject

}

}

}

xhr.send()

})

}

let p1 = sendAjax('http://www.atguigu.com')

p1.then(function (data) {

console.log('成功了')

console.log(data)

}, function () {

console.log('失败了')

})

let p2 = sendAjax('http://www.atguigu.com')

p2.then(function (data) {

console.log('成功了')

console.log(data)

}, function () {

console.log('失败了')

})

3. async/await

使用async/await可以处理promise链式调用过长问题,async/await可以让我们同步书写请求嵌套,看起来更舒服:

// 假设有这么一个情况:

// 现有一个A请求,然后B请求依赖A请求返回的数据,C请求依赖B请求返回的数据...

// 如果是promise写

post('A', data)

.then(res1 => post('B', res1))

.then(res2 => post('C', res2))

.then(res3 => post('D', res3))

.then(res4 => post('E', res4))

...

// 换成async/await写

async handler() {

let a = await post('A', data)

let b = await post('B', a)

let c = await post('C', b)

let d = await post('D', c)

...

}

总结

async/await 可以直接拿到 Promise 的结果,可以代替 then() 方法和回调函数。可以取代链式调用,是回调地狱的终极解决方案。缺点是状态为 rejected 的 Promise 实例,会抛出异常,所以需要写在 try...catch结构中防止出错。

相关推荐

总结下SpringData JPA 的常用语法

SpringDataJPA常用有两种写法,一个是用Jpa自带方法进行CRUD,适合简单查询场景、例如查询全部数据、根据某个字段查询,根据某字段排序等等。另一种是使用注解方式,@Query、@Modi...

解决JPA在多线程中事务无法生效的问题

在使用SpringBoot2.x和JPA的过程中,如果在多线程环境下发现查询方法(如@Query或findAll)以及事务(如@Transactional)无法生效,通常是由于S...

PostgreSQL系列(一):数据类型和基本类型转换

自从厂子里出来后,数据库的主力就从Oracle变成MySQL了。有一说一哈,贵确实是有贵的道理,不是开源能比的。后面的工作里面基本上就是主MySQL,辅MongoDB、ES等NoSQL。最近想写一点跟...

基于MCP实现text2sql

目的:基于MCP实现text2sql能力参考:https://blog.csdn.net/hacker_Lees/article/details/146426392服务端#选用开源的MySQLMCP...

ORACLE 错误代码及解决办法

ORA-00001:违反唯一约束条件(.)错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常。ORA-00017:请求会话以设置跟踪事件ORA-00018:超出最大会话数ORA-00...

从 SQLite 到 DuckDB:查询快 5 倍,存储减少 80%

作者丨Trace译者丨明知山策划丨李冬梅Trace从一开始就使用SQLite将所有数据存储在用户设备上。这是一个非常不错的选择——SQLite高度可靠,并且多种编程语言都提供了广泛支持...

010:通过 MCP PostgreSQL 安全访问数据

项目简介提供对PostgreSQL数据库的只读访问功能。该服务器允许大型语言模型(LLMs)检查数据库的模式结构,并执行只读查询操作。核心功能提供对PostgreSQL数据库的只读访问允许L...

发现了一个好用且免费的SQL数据库工具(DBeaver)

缘起最近Ai不是大火么,想着自己也弄一些开源的框架来捣腾一下。手上用着Mac,但Mac都没有显卡的,对于学习Ai训练模型不方便,所以最近新购入了一台4090的拯救者,打算用来好好学习一下Ai(呸,以上...

微软发布.NET 10首个预览版:JIT编译器再进化、跨平台开发更流畅

IT之家2月26日消息,微软.NET团队昨日(2月25日)发布博文,宣布推出.NET10首个预览版更新,重点改进.NETRuntime、SDK、libraries、C#、AS...

数据库管理工具Navicat Premium最新版发布啦

管理多个数据库要么需要使用多个客户端应用程序,要么找到一个可以容纳你使用的所有数据库的应用程序。其中一个工具是NavicatPremium。它不仅支持大多数主要的数据库管理系统(DBMS),而且它...

50+AI新品齐发,微软Build放大招:拥抱Agent胜算几何?

北京时间5月20日凌晨,如果你打开微软Build2025开发者大会的直播,最先吸引你的可能不是一场原本属于AI和开发者的技术盛会,而是开场不久后的尴尬一幕:一边是几位微软员工在台下大...

揭秘:一条SQL语句的执行过程是怎么样的?

数据库系统能够接受SQL语句,并返回数据查询的结果,或者对数据库中的数据进行修改,可以说几乎每个程序员都使用过它。而MySQL又是目前使用最广泛的数据库。所以,解析一下MySQL编译并执行...

各家sql工具,都闹过哪些乐子?

相信这些sql工具,大家都不陌生吧,它们在业内绝对算得上第一梯队的产品了,但是你知道,他们都闹过什么乐子吗?首先登场的是Navicat,这款强大的数据库管理工具,曾经让一位程序员朋友“火”了一把。Na...

详解PG数据库管理工具--pgadmin工具、安装部署及相关功能

概述今天主要介绍一下PG数据库管理工具--pgadmin,一起来看看吧~一、介绍pgAdmin4是一款为PostgreSQL设计的可靠和全面的数据库设计和管理软件,它允许连接到特定的数据库,创建表和...

Enpass for Mac(跨平台密码管理软件)

还在寻找密码管理软件吗?密码管理软件有很多,但是综合素质相当优秀且完全免费的密码管理软件却并不常见,EnpassMac版是一款免费跨平台密码管理软件,可以通过这款软件高效安全的保护密码文件,而且可以...