ES7 Async
ES8 标准引入异步函数,配合await关键字简化了异步操作,使异步代码几乎和同步代码一致;
- 异步函数函数使用
async关键字修饰函数,异步函数内的返回值会被包装成 Promise 对象; - 异步函数使用
await关键字配 Promise 才能发挥真正的优势,await关键字只在异步函数内才有效。在异步函数内部执行使用await关键字修饰 Promise 对象实例会暂停执行,直到实例pending状态结束。await会并返回实例resolve的值 - 一般
await关键字后面是一个 Promise 实例,也可以其它数据类型,其它数据类会立即被转换为一个 Promise 的resolve值;不过这种代码并没有实际意义。
基本示例
异步函数和Promise配合使用可以快速写出简洁的异步代码;
// 延迟执行函数
function delayRun(str, delay) {
return new Promise((resolve) => {
setTimeout(() => resolve(str), delay);
})
}
async function asyncPoint() {
var l1 = await delayRun("Line1", 3000);
console.log(l1);// 3秒钟后执行
var l2 = await "Line2";
console.log(l2);// 立即执行
var l3 = await delayRun("Line3", 3000);
console.log(l3);// 3秒钟后执行
return l1 + l2 + l3;// 返回数据会自动包装成Promise对象
}
console.log('Code Start Run')
asyncPoint().then((data) => {
console.log(data)
});
console.log('Code Finish')
// 运行结果
// Code Start Run
// Code Finish
// Line1 // 延迟执行
// Line2 // 立即执行
// Line3 // 延迟执行
// Line1Line2Line3
异常处理
通常 Promise 实例的异常只能通过.catch()进行捕捉,但是在异步函数中可以使用try catch语句捕捉。
async function f() {
try {
await Promise.reject('出错了');
} catch (e) {
console.log(e); // 出错了
}
await Promise.reject('又出错了')
.catch(e => console.log(e)); // 又出错了
return 'hello world';
}
f().then(v => console.log(v)) // hello world
await 函数同时触发
async函数内部的多个await默认顺序执行,一个执行完成之后再执行下一个,如果多个await不存在相互依赖并发执行会消耗更少的运行时间;
// 写法一
let [foo, bar] = await Promise.all([getFoo(), getBar()]);
// 写法二
let fooPromise = getFoo();
let barPromise = getBar();
let foo = await fooPromise;
let bar = await barPromise;