通过async可以快速的创建异步函数
异步函数的返回值会自动封装到一个Promise中返回
在async声明的异步函数中可以使用await关键字来调用异步函数
function sum(a, b) {
return new Promise(resolve => {
setTimeout(() => {
resolve(a + b);
}, 2000);
});
}
Promise解决了异步调用中的回调函数的问题
虽然通过链式调用解决了回调地狱,但是还是不好看,想用同步的方式去调用异步的代码
如果async声明的函数中没有写await,那么他里面的代码就会依次执行(async返回值是Promise)
async function fn2() {
// sum(123, 456)
// .then(r => sum(r, 8))
// .then(r => sum(r, 8))
// .then(r => console.log(r));
// 当我们通过await去调用异步函数时,它会暂停代码的运行,直到异步代码有结果是,才会将结果返回
// 注意 await只能用于async声明的异步函数中,或es模块的顶级作用域中
// await阻塞的只是异步函数内部的代码,不会影响外部代码
// 通过await调用异步代码时,需要通过try-catch来处理异常
try {
let result = await sum(123, 456);
result = await sum(result, 8);
result = await sum(result, 9);
console.log(result);
console.log(123); // 该代码会被await阻塞
} catch (e) {
console.log('出错了------');
}
}
fn2();
console.log('全局中的输出----');
/*
当我们使用await调用函数后,当前函数后面的所有代码会在当前函数执行完毕后,被放入微任务队列中
*/
// 顺序为1 2 4 3
async function fn3() {
console.log(1);
await console.log(2);
console.log(3);
}
/*
// 等价于
function fn3() {
return new Promise(resolve => {
console.log(1);
console.log(2);
resolve();
}).then(r => {
console.log(3);
});
}
*/
fn3();
console.log(4);
// 在非模块中调用await
(async () => {
await console.log('哈哈哈');
})();
<script type="module">// 转换为模块
/*
直接调await会
Uncaught SyntaxError: await is only valid in async functions and the top level bodies of modules
*/
await console.log(123);
</script>