公司的前端工程使用了ES6语法,最近看代码的时候还是有很多疑惑的,本文主要记录一下async/await相关知识
1. async
使用谷歌浏览器开发者工具写脚本进行测试
- 按F12打开开发者工具
- 点击
Source - 在左侧选择
Snippets,点击New snippets创建一个新文件

- 输入以下代码
async function add(x) { let a = 1; return x + a; } add(10); - 运行此脚本,在控制台可以看到有结果输出

- 返回的结果是一个Promise对象,状态是
fulfilled,值是11

2. await
- await 放置在Promise调用之前,强制后面的代码等待,直到Promise对象resolve,得到resolve的值作为await表达式的运算结果
- await只能在async函数内部使用,用在普通函数里会报错
-
新建一个脚本文件,输入以下代码:
function test_promise() { return new Promise(function(resolve, reject) { resolve('resolve result') }); } async function run_test() { let a = await test_promise() let b = await ' and a simple string' console.log(a) console.log(b) return a + b } run_test();运行结果为:

-
给test_promise方法添加延时,修改test_promise()方法
function test_promise() { return new Promise(function(resolve, reject) { setTimeout(() => { resolve('resolve result') }, 3000) }); }运行结果为:

注意,PromiseResult的值即为run_test()方法的返回值
3. 错误处理
-
未捕获错误
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => {reject('error')}, ms); }); } async function asyncPrint(ms) { console.log('start'); await timeout(ms); //这里返回了错误 console.log('end'); //所以这句代码不会被执行了 } asyncPrint(1000);运行结果:

本例中我们并没有捕获错误,控制台打印 Uncaught error
-
捕获错误
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => {reject('error')}, ms); //reject模拟出错,返回error }); } // 使用 try catch 捕获异常,包括promise对象reject的数据或者抛出的异常 async function asyncPrint(ms) { try { console.log('start'); await timeout(ms); console.log('end'); } catch(err) { console.log(err); } } asyncPrint(1000);或者使用如下方式
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => {reject('error')}, ms); //reject模拟出错,返回error }); } async function asyncPrint(ms) { console.log('start'); await timeout(ms) console.log('end'); } asyncPrint(1000).catch(err => { console.log(err) });运行结果:
首先打印了start,然后在执行timeout函数时,调用reject回调。错误被捕获,打印出"error"。

-
如果想在出现异常后仍然执行后续代码,示例代码如下:
function timeout(ms) { return new Promise((resolve, reject) => { setTimeout(() => { reject('error') }, ms); }); } async function asyncPrint(ms) { console.log('start'); await timeout(ms).catch(err => { console.log(err) }) console.log('end'); } asyncPrint(1000);运行结果:

4. Promise.all()
多个await命令的异步操作,如果不存在依赖关系(后面的await不依赖前一个await返回的结果),用Promise.all()让它们同时触发
function test1 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(1)
}, 1000)
})
}
function test2 () {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 2000)
})
}
async function exc1 () {
console.log('exc1 start:',Date.now())
let res1 = await test1();
let res2 = await test2();
console.log('exc1 end:', Date.now())
}
async function exc2 () {
console.log('exc2 start:',Date.now())
let [res1, res2] = await Promise.all([test1(), test2()])
console.log('exc2 end:', Date.now())
}
exc1();
exc2();
运行上述代码可得,执行exc1函数耗时约为3秒,而执行exc2函数耗时约为2秒。表明在exc2函数中, 使用Promise.all同时触发了test1和test2这2个异步函数。
参考:
本文详细介绍了ES6中的async/await用法,通过实例展示了如何使用async函数和await关键字处理Promise。从基本概念到错误处理,再到Promise.all()的并行执行,阐述了异步编程的核心技巧。同时,文中还提供了错误捕获的方法,确保程序的健壮性。
1611

被折叠的 条评论
为什么被折叠?



