1. Promise
异步函数,即async / await,是基于Promise的应用,可以让我们以同步的方式写异步的代码。
如下代码,一个使用Promise的简单例子,Promise对象中的函数参数中,写了一个定时器setTimeout。定时器的第三个参数为10,表示定时器结束后,10将作为参数,传递给定时器的回调函数resolve。这就意味着,定时器结束后,这个Promise对象会解决为数值10。
const p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 10));
但是,如果访问到这个数值10,需要调用then()方法:
p.then(x => console.log(x)); // 10
这非常不方便,虽然解决了回调地域问题,但是后续代码必须要放在then()方法里面。
在 ES8 中,JavaScript 支持了async / await关键字,可以用同步的方式,写异步代码。
2. async 关键字
async关键字用来声明异步函数,可以在函数声明、函数表达式、箭头函数、方法前声明使用:
// 函数声明
async function fun1() {}
// 函数表达式
const fun2 = async function () {};
// 箭头函数
const fun3 = async () => {};
// 方法
const obj = {
async fun4() {},
};
使用async关键字可以让函数具有异步的特征,但代码还是同步求值的:
async function fun() {
console.log(1);
}
fun();
console.log(2);
// 1
// 2
如上代码,fun函数被声明成异步函数,但总体代码仍然是同步执行的,因为先打印出了1,再打印2。
另外,被async声明的函数如果使用return返回了值(若没有return,则返回undefined),那么返回的值会被Promise.resolve()包装成一个Promise对象。所以,异步函数始终会返回Promise对象。
如下代码,调用fun函数,fun函数内部首先打印出1,接着返回Promise对象,然后打印出2,最后打印出Promise对象解决的值3。
async function fun() {
console.log(1);
return 3;
}
fun().then(console.log);
console.log(2);
// 1
// 2
// 3
异步函数内部直接返回一个Promise对象也能达到同样效果,如下代码等价于上面的代码:
async function fun() {
console.log(1);
return Promise.resolve(3);
}
fun().then(console.log);
console.log(2);
// 1
// 2
// 3
但是,若Promise被拒绝,那么将不会被异步函数捕获:
async function fun() {
console.log(1);
Promise.reject(3);
}
fun().then(console.log);
console.log(2);
// 1
// 2
// 报错:Unhandled promise rejection
3. await 关键字
使用await关键字可以暂停异步函数代码的执行,等待Promise解决。
本文首个例子:
const p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 10));
p.then(x => console.log(x)); // 10
可以使用async和await关键字改写为:
async function fun() {
const p = new Promise((resolve, reject) => setTimeout(resolve, 1000, 10));
console.log(await p);
}
fun(); // 10
await关键字会暂停执行异步函数后面的代码,让出 JavaScript 运行时的执行线程。
但是,await必须和async一起使用,也就是说,await只能写在被async声明过的异步函数中。若await写在同步函数中,将会报错:
function fun() {
let a = await 1; // SyntaxError: await is only valid in async function
console.log(a);
}
fun();
参考:
《JavaScript高级程序设计(第4版)》
📘📘欢迎在我的博客上访问:
https://lzxjack.top/
本文介绍了JavaScript中的异步编程概念,重点讲解了Promise和async/await的使用。通过实例展示了如何用async关键字声明异步函数,以及await关键字如何暂停执行并等待Promise解决。文章还探讨了await只能在async函数中使用的规定,以及Promise被拒绝时的处理。
809

被折叠的 条评论
为什么被折叠?



