JavaScript中的async/await详解
1、前言
async函数,也就是我们常说的async/await,是在ES2017(ES8)引入的新特性,主要目的是为了简化使用基于Promise的API时所需的语法。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为,而无需刻意地链式调用Promise。
2、详解
async表示函数里有异步操作,await表示紧跟在后面的表达式需要等待结果。需要注意的是await关键字只在async函数内有效,如果在async函数体之外使用它,会抛出语法错误。
2.1、async
async函数返回一个 Promise对象,可以使用then方法添加回调函数。只要使用async,不管函数内部返回的是不是Promise对象,都会被包装成Promise对象。
话不多说,上代码看效果:
2.1.1、函数返回非Promise对象
async function testAsync() {
return "hello async";
}
const result = testAsync();
console.log(result);

可以看出函数直接返回字符串时,返回的是Promise对象,相当于直接通过Promise.resolve()将字符串封装为Promise对象。如果函数没有返回值时,PromiseResult结果为undefined。
2.1.2、函数返回Promise对象
async function testAsync() {
return new Promise(function(resolve, reject) {
if (true) {
resolve('resolve return')
} else {
reject('reject return')
}
})
}
console.log(testAsync());

可以看出返回的也是Promise对象。
2.2、await
await关键字可以跟在任意变量或者表达式之前,但通常await后面会跟一个异步过程。await使用时,会阻塞后续代码执行。我们先抛开async,单独谈await。
由于await只能在async标识的函数内使用,以下例子请在浏览器控制台执行看效果。
function testAsync() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
if (true) {
console.log('请求中...')
resolve('resolve return')
} else {
reject('reject return')
}
}, 2000)
})
}
var result = await testAsync();
var result1 = await "testAsync后执行";
console.log(result);
console.log(result1);

可以看出,使用了await后,必须得等testAsync方法执行完后,才会执行后续代码。您也可以尝试一下把testAsync前的async去掉,看看跟加上await时有啥区别。
2.3、async、await结合使用
上面我们知道了await会阻塞后续代码运行,那怎么解决这个问题呢?就需要用到async,使用async后,函数执行时,一旦遇到await就会先返回一个Promise对象,等到await的操作完成后,再接着执行函数体内的语句。
先上语法:
async function 函数名() {
await XXX;
}
上示例代码:
function testAsync() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
if (true) {
console.log('请求中...')
resolve('resolve return')
} else {
reject('reject return')
}
}, 2000)
})
}
function testAsync2() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
if (true) {
console.log('请求中2...')
resolve('resolve return2')
} else {
reject('reject return2')
}
}, 2000)
})
}
async function test() {
console.log('test开始...');
var value1 = await testAsync();
console.log(value1);
var value2 = await testAsync2();
console.log(value2);
var value3 = await 'test结束...';
console.log(value3);
}
console.log(test());

上图可以看出遇到第一个await后,立即返回了Promise对象,然后再按顺序去执行testAsync函数,等待testAsync函数执行后再去执行testAsync2函数。
我们再升级一下,在上面的基础上再加入两个普通函数:
function fun1() {
return '函数1'
}
function fun2() {
return '函数2'
}
function fun3() {
console.log(fun1());
console.log(test()); // async/await函数
console.log(fun2());
}
console.log(fun3());

我们梳理一下函数的执行过程,
1、先执行函数1
2、进入test函数并输出开始
3、在test函数中遇到await,立即返回Promise对象
4、执行函数2
5、执行test函数中的testAsync方法
6、等到test函数中的testAsync方法执行完后,继续执行testAsync2方法
7、test函数结束
可以看出,async函数在遇到await后会立即返回Promise对象,继续执行async函数外部后续逻辑,async函数内部会被await阻塞并按顺序执行代码逻辑。
2.4、async、await异常处理
await后面的函数是有可能出现异常的,所以最好把await命令放在try...catch代码块中。如果await后是Promise对象,也可以使用.catch进行捕获。
// 第一种写法
async function myFunction() {
try {
await something();
} catch (err) {
console.log(err);
}
}
// 第二种写法
async function myFunction() {
await somethingPromise()
.catch(function (err) {
console.log(err);
});
}
3、总结
async函数在遇到await后会立即返回Promise对象,继续执行async函数外部逻辑,async函数内部会被await阻塞并按顺序执行代码逻辑。
可以使用try...catch或.catch对async函数进行异常处理。
JavaScript中的async/await详解的更多相关文章
- Promise和async await详解
本文转载自Promise和async await详解 Promise 状态 pending: 初始状态, 非 fulfilled 或 rejected. fulfilled: 成功的操作. rejec ...
- javascript中=、==、===区别详解
javascript中=.==.===区别详解今天在项目开发过中发现在一个小问题.在判断n==""结果当n=0时 n==""结果也返回了true.虽然是个小问题 ...
- JavaScript中return的用法详解
JavaScript中return的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 t ...
- javascript 中合并排序算法 详解
javascript 中合并排序算法 详解 我会通过程序的执行过程来给大家合并排序是如何排序的... 合并排序代码如下: <script type="text/javascript& ...
- javascript中的this作用域详解
javascript中的this作用域详解 Javascript中this的指向一直是困扰我很久的问题,在使用中出错的机率也非常大.在面向对象语言中,它代表了当前对象的一个引用,而在js中却经常让我觉 ...
- JavaScript中this的用法详解
JavaScript中this的用法详解 最近,跟身边学前端的朋友了解,有很多人对函数中的this的用法和指向问题比较模糊,这里写一篇博客跟大家一起探讨一下this的用法和指向性问题. 1定义 thi ...
- JavaScript中数组Array方法详解
ECMAScript 3在Array.prototype中定义了一些很有用的操作数组的函数,这意味着这些函数作为任何数组的方法都是可用的. 1.Array.join()方法 Array.join()方 ...
- Javascript中的async await
async / await是Javascript是ES7的重要特性之一,也是目前社区里公认的优秀异步解决方案.目前,async / await这个特性已经是stage 3的建议,可以看看TC39的进度 ...
- async await详解
async await本身就是promise + generator的语法糖. 本文主要讲述以下内容 async awiat 实质 async await 主要特性 async await 实质 下面 ...
随机推荐
- Markdown插入LaTex数学公式
本文转载自Nautilus_sailing的试试LaTeX插入数学公式,内容有所改动 今天写了一篇随笔,其中需要写几个数学式子,但是我又不想直接将公式做成图片后插入,我觉得很不美观还麻烦.但是我也不会 ...
- Golang语言系列-05-数组和切片
数组和切片 数组 概念 数组是同一种数据类型元素的集合:数组的长度必须是常量,并且长度是数组类型的一部分,一旦定义,长度不能变 例如:[5]int 和 [10]int 是不同的数组类型 使用时可以修改 ...
- LNMP 方式部署 zabbix 5.0
文章链接 Zabbix 5.0 LTS新增功能 新版本附带了可用性,安全性和完整性方面的重大改进列表.Zabbix团队遵循的主要策略是使Zabbix尽可能可用.Zabbix是一种开源,免费的监视解决方 ...
- NOIP 模拟 $18\; \rm 老司机的狂欢$
题解 \(by\;zj\varphi\) 一道很有趣的题,我用的动态开点线段树和倍增 首先对于第一问,不难想到要二分,二分时间,因为时间长一定不会比时间短能跑的人多 那么如何 check,先将所有老司 ...
- 题解 Walker
传送门 总觉得有个柿子可以推--然而没推出来 考试的时候有个柿子假了导致我没想用两个点可以解出一组参数的事 假掉的柿子告诉我有不少东西能消掉 然而实际上随便选两个点高斯消元解出一组参数,再代入验证看够 ...
- [转]C# 互操作性入门系列(四):在C# 中调用COM组件
传送门 C#互操作系列文章: C# 互操作性入门系列(一):C#中互操作性介绍 C# 互操作性入门系列(二):使用平台调用调用Win32 函数 C# 互操作性入门系列(三):平台调用中的数据封送处理 ...
- Quartz任务调度(4)JobListener分版本超详细解析
JobListener 我们的jobListener实现类必须实现其以下方法: 方法 说明 getName() getName() 方法返回一个字符串用以说明 JobListener 的名称.对于注册 ...
- ffmpeg 常用知识点收集
ffmpeg 常用知识点收集 一.基础简介 FFmpeg是一个自由软件,可以运行音频和视频多种格式的录影.转换.流功能,包含了libavcodec ─这是一个用于多个项目中音频和视频的解码器库,以及l ...
- ProjectEuler 008题
题目: The four adjacent digits in the 1000-digit number that have the greatest product are 9 9 8 9 = 5 ...
- VS code快速创建vue模板
忘记了.vue文件的格式或者不想手动敲那段模板代码怎么办?VS code快速创建vue模板帮你偷个小懒 第一步:新建模板并保存 打开 VS code,依次点击 file > Preference ...