ES8 (async/await)异步函数

最后更新:
阅读次数:

尴尬,刚开始一直以为异步函数是属于 ES7 的,但是最近无意中发现一个查看 ES 特性兼容性的网站,才发现原来异步函数是属于 ES2017,,即 ES8。

http://kangax.github.io/compat-table/es2016plus/

初识异步函数

我们来简单对比一下异步函数与普通函数的区别。

 异步函数普通函数
声明async functionfunction
所属类型AsyncFunctionFunction
返回值只能返回一个 promise 对象可返回任意类型的值
  • AsyncFunction 继承自 Function

  • 当异步函数使用 return 语句返回值时,promise 的 resolve 方法将会处理这个返回值

async function asyncFunc() {
return 666;
}

console.log(asyncFunc); // [AsyncFunction: asyncFunc]
console.log(asyncFunc()); // Promise { 666 }

asyncFunc()
.then(function(data) {
console.log(data); // 666
})
.catch(function(err) {
console.log(err);
});

await 操作符

await 操作符后可以跟一个 Promise 或者 其它任何等待解析的值。如果 await 后跟的是 promise,则 await 语句返回 promise 的 resolved 的值,否则返回值本身。

  • await 语句表示异步函数先暂停在这里等待,等到 promise 返回结果后,再继续执行异步函数

  • await 操作符只能用于异步函数中,并且 await 必须在 async 函数的上下文中的。

// 循环多个 await

// 错误
async function asyncFunc() {
let arr = ["a", "b", "c"];

arr.forEach(el => {
// 报错
console.log(await el);
});
}

// 正确
async function asyncFunc() {
let arr = ["a", "b", "c"];

for (let i = 0; i < arr.length; i++) {
console.log(await arr[i]);
}
}
  • 捕捉异步函数中的错误

因为 await 语句返回的是 promise 的 resolved 值,默认是不会捕获错误的,所以我们最好在异步函数中使用 try-catch 语句捕获错误。

let sleep = function(time) {
return new Promise(function(resolve, reject) {
setTimeout(function() {
// 模拟出错,返回 error
reject("error");
}, time);
});
};

let start1 = async function() {
console.log("start1");
await sleep(1000); // 发生了错误

// 以下代码不会被执行
console.log("end1");
};

let start2 = async function() {
try {
console.log("start2");
await sleep(1000); // 发生了错误

// 以下代码不会被执行
console.log("end2");
} catch (err) {
console.log(err); // 捕获错误
}
};

start1();
start2();
# 运行上面的代码,会得到下面的信息
start1
start2
(node:2164) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): error
(node:2164) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
error