异步编程之async/await
先导语
在上一节中我们学习了event-loop事件循环机制,这节我们来学习下异步编程之async/await。 大家应该都听说过一句话:async/await 是异步编程的终极解决方案。那么下面我们就来体验下async/await的魅力吧!
async
首先,我们先来看一段代码:
console.log(async function(){})
在一个方法前面加上async关键字,然后打印出来,会得到怎样的结果呢?答案是:
[AsyncFunction (anonymous)] 返回的是结果表示这是一个异步的方法。可能大家感觉也没什么特别的,那我们再来看下面这段代码:
console.log(async function () {});
console.log(function () {
return new Promise((resolve, reject) => {
resolve(6);
});
});
得到的结果是:
从结果上,我们可以看出,只有加了async的方法才会返回 AsyncFunction,没有async关键字的方法返回的只是一个 Function 。
我们再改变下这段代码:
console.log((async function () {})());
console.log(
(function () {
return new Promise((resolve, reject) => {
resolve(6);
});
})()
);
这里我们把两个方法都变成了立即执行的方法,然后我们得到如下结果:
这里,我们得到两个Promise对象,但是这两个Promise对象的来历是不同的,第一个方法会返回一个Promise对象,是因为async关键字。第二个会返回Promise对象是因为我们在函数内部返回了一个Promise对象。
这里我们可以得到一个结论:async关键字会把一个方法声明为一个异步方法,并且会将方法返回的值包装成一个promise对象。async其实就是一个promise的语法糖封装!
await
关于await,这里我们先给出结论:
1. await会阻塞进程
2. await可以进行表达式求值
3. 使用await可以使异步操作内抛出的错误被try...catch捕获
接下来,我们就可以通过举例去挨个去验证await的这几个特点了。
await会阻塞进程
async function test() {
await new Promise((resolve, reject) => {
setTimeout(() => {
console.log("1");
resolve("1");
}, 1000);
});
console.log("2");
}
test();
代码输出结果为:
当我们把await去掉:
async function test() {
new Promise((resolve, reject) => {
setTimeout(() => {
console.log("1");
resolve("1");
}, 1000);
});
console.log("2");
}
test();
结果为:
从这两段代码的对比中,我们可以得到await会阻塞进程的结论。
await可以进行表达式求值
demo1:
async function test() {
let a = await new Promise((resolve, reject) => {
setTimeout(() => {
resolve("1");
}, 1000);
});
console.log(a);
}
test();
结果:
demo2:
async function test() {
let a = await (2 * 3 + 5);
console.log(a);
}
test();
结果:
demo3:
async function test() {
let a = await new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("test"));
}, 1000);
});
console.log(a);
}
test();
结果:
使用await可以使异步操作内抛出的错误被try...catch捕
首先我们先来看看,没有使用await的时候,try...catch 是否可以捕获异步任务中抛出的错误。
function test() {
try {
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("test"));
}, 1000);
});
} catch (error) {
console.log(error);
}
}
test();
在浏览器中运行的结果:全局抛出一个错误!
加了await关键字的情况:
async function test() {
try {
await new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error("test"));
}, 1000);
});
} catch (error) {
console.log(error);
}
}
test();
结果:错误被catch方法捕捉到了!
结束语
关于async和await的理解就到这里了。那么,下次见。好好学习,天天向上!