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

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

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

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结构中防止出错。

相关推荐

MySQL合集-mysql5.7及mysql8的一些特性

1、Json支持及虚拟列1.1jsonJson在5.7.8原生支持,在8.0引入了json字段的部分更新(jsonpartialupdate)以及两个聚合函数,JSON_OBJECTAGG,JS...

MySQL 双表架构在房产中介房源管理中的深度实践

MySQL房源与价格双表封神:降价提醒实时推送客户房产中介实战:MySQL空间函数精准定位学区房MySQL狠招:JSON字段实现房源标签自由组合筛选房源信息与价格变更联动:MySQL黄金搭档解决客户看...

MySQL 5.7 JSON 数据类型使用总结

从MySQL5.7.8开始,MySQL支持原生的JSON数据类型。MySQL支持RFC7159定义的全部json数据类型,具体的包含四种基本类型(strings,numbers,boolea...

MySQL 8.0 SQL优化黑科技,面试官都不一定知道!

前言提到SQL优化,大多数人想到的还是那些经典套路:建索引、避免全表扫描、优化JOIN顺序…这些确实是基础,但如果你还停留在MySQL5.7时代的优化思维,那就out了。MySQL8.0已经发布好...

如何在 MySQL 中使用 JSON 数据(mysql的json函数与实例)

在MySQL中学习“NoSQL”MySQL从5.7版本开始就支持JSON格式的数据类型,该数据类型支持JSON文档的自动验证和优化存储和访问。尽管JSON数据最好存储在MongoDB等...

MySQL中JSON的存储原理(mysql中json字段操作)

前言:表中有json字段后,非索引查询性能变得非常糟糕起因是我有一张表,里面有json字段后,而当mysql表中有200w数据的时候,走非索引查询性能变得非常糟糕需要3到5s。因此对mysql的jso...

mysql 之json字段详解(多层复杂检索)

MySQL5.7.8开始支持JSON数据类型。MySQL8.0版本中增加了对JSON类型的索引支持。示例表CREATETABLE`users`(`id`intNOTNULLAU...

VMware vCenter Server 8.0U3b 发布下载,新增功能概览

VMwarevCenterServer8.0U3b发布下载,新增功能概览ServerManagementSoftware|vCenter请访问原文链接:https://sysin.or...

Spring Boot 3.x 新特性详解:从基础到高级实战

1.SpringBoot3.x简介与核心特性1.1SpringBoot3.x新特性概览SpringBoot3.x是建立在SpringFramework6.0基础上的重大版...

如何设计Agent的记忆系统(agent记忆方法)

最近看了一张画Agent记忆分类的图我觉得分类分的还可以,但是太浅了,于是就着它的逻辑,仔细得写了一下在不同的记忆层,该如何设计和选型先从流程,作用,实力和持续时间的这4个维度来解释一下这几种记忆:1...

Spring Boot整合MyBatis全面指南:从基础到高级应用(全网最全)

一、基础概念与配置1.1SpringBoot与MyBatis简介技术描述优点SpringBoot简化Spring应用开发的框架,提供自动配置、快速启动等特性快速开发、内嵌服务器、自动配置、无需X...

5大主流方案对比:MySQL千亿级数据线上平滑扩容实战

一、扩容方案剖析1、扩容问题在项目初期,我们部署了三个数据库A、B、C,此时数据库的规模可以满足我们的业务需求。为了将数据做到平均分配,我们在Service服务层使用uid%3进行取模分片,从而将数据...

PostgreSQL 技术内幕(五)Greenplum-Interconnect模块

Greenplum是在开源PostgreSQL的基础上,采用MPP架构的关系型分布式数据库。Greenplum被业界认为是最快最具性价比的数据库,具有强大的大规模数据分析任务处理能力。Greenplu...

在实际操作过程中如何避免出现SQL注入漏洞

一前言本文将针对开发过程中依旧经常出现的SQL编码缺陷,讲解其背后原理及形成原因。并以几个常见漏洞存在形式,提醒技术同学注意相关问题。最后会根据原理,提供解决或缓解方案。二SQL注入漏洞的原理、形...

运维从头到尾安装日志服务器,看这一篇就够了

一、rsyslog部署1.1)rsyslog介绍Linux的日志记录了用户在系统上一切操作,看日志去分析系统的状态是运维人员必须掌握的基本功。rsyslog日志服务器的优势:1、日志统一,集中式管理...