x-note
Search…
ECMAScript 8 async 函数
ES8 正式将 async 函数记入 state-4 阶段

async 函数的声明

一般声明
1
async function fn() {}
Copied!
async 函数表达式
1
const fn = async function () {};
Copied!
async 方法
1
let obj = { async method() {} }
Copied!
async 箭头函数
1
const foo = async () => {};
Copied!
class 内部声明 async 函数
1
class A {
2
async method() {}
3
}
Copied!
async 函数总会返回 Promise 实例
1
async function asyncFunc() {
2
return 123;
3
}
4
asyncFunc().then(x => console.log(x)); // 123
5
6
async function asyncFunc() {
7
throw new Error('Problem!');
8
}
9
asyncFunc().catch(err => console.log(err)); // Error: Problem!
Copied!

通过 await 操作符处理异步计算

await操作符(只允许在 async 函数中)后面是一个 Promise 对象(如果不是,将立即转成resolved的 Promise ),await 会等待 Promise 从 pending 状态变更后,再继续往后执行。
  • 如果 Promise 的状态是resolvedawiat的结果就是 resolved value
  • 如果 Promise 的状态是rejectedawait将会抛出 rejection valuse
1
async function asyncFunc() {
2
const result = await 1;
3
console.log(result + 1);
4
}
5
6
// 等同于
7
function asyncFunc() {
8
return Promise.resolve(1)
9
.then(result => {
10
console.log(result + 1);
11
});
12
}
13
14
async function f() {
15
const result = await Promise.reject('出错了');
16
console.log(result);
17
await Promise.resolve('hello world'); // 不会执行
18
}
Copied!
处理异常
1
async function asyncFunc() {
2
try {
3
await otherAsyncFunc();
4
} catch (err) {
5
console.error(err);
6
}
7
}
8
9
// 等同于:
10
function asyncFunc() {
11
await otherAsyncFunc().catch(err => {
12
console.error(err);
13
});
14
}
15
16
// 等同于:
17
function asyncFunc() {
18
return otherAsyncFunc()
19
.catch(err => {
20
console.error(err);
21
});
22
}
Copied!
对比 Promise.all()。await 是队列进行的,Promise.all()是并行进行的。
1
let counter = 0
2
function fn1 (msg) {
3
return new Promise((resolve, reject) => {
4
if (!counter) {
5
setTimeout(() => {
6
counter++
7
resolve(counter)
8
}, 1000)
9
console.log(msg)
10
} else {
11
reject(new Error(`cannot excute [${msg}], because counter > 0`))
12
}
13
})
14
}
15
16
async function asyncFn () {
17
await fn1('async fn 1').catch(err => { console.log(err.msg) })
18
await fn1('async fn 2').catch(err => { console.log(err.msg) })
19
}
20
21
asyncFn()
22
23
Promise.all([
24
fn1('Promise.all 1'),
25
fn1('Promise.all 2')
26
])
27
28
// async fn 1
29
// Promise.all 1
30
// Promise.all 2
31
// cannot excute async [fn 2], because counter > 0
Copied!

async 函数的执行过程

async 函数是同步开始,异步结束的
  1. 1.
    async 函数的结果永远是一个 Promise 对象 p,这个 Promise 在开始执行异步函数的时候创建
  2. 2.
    async 函数体被执行。通过returnthrow返回最终的执行结果,又或者通过await返回临时结果;这些结果通常都是延迟返回的;
  3. 3.
    返回 Promise p
当执行 async 函数体时,return x将会使 Promise presolved状态返回 xthrow err将会使 Promise prejected状态返回 err。执行结果的通知是异步发生的。换句话说,then()catch()总是在当前代码执行结束之后再执行。
1
async function asyncFunc() {
2
console.log('asyncFunc()'); // (A)
3
return 'abc';
4
}
5
asyncFunc().
6
then(x => console.log(`Resolved: ${x}`)); // (B)
7
console.log('main'); // (C)
8
9
// Output:
10
// asyncFunc()
11
// main
12
// Resolved: abc
Copied!
分析上述代码:
  1. 1.
    Line(A): 同步调用 async 函数,async 函数的 promise 通过 return 变成 resolved 状态
  2. 2.
    Line(C): 继续执行
  3. 3.
    Line(B): 异步通知 Promise 状态变更