一、概述
案例:
async function asyncReadFile () {
const f1 = await readFile('/etc/fstab');
const f2 = await readFile('/etc/shells');
console.log(f1.toString());
console.log(f2.toString());
};
asyncReadFile();
async
表示函数里有异步操作,await
表示紧跟在后面的表达式需要等待结果。 await
命令后面,可以是 Promise 对象和原始类型的值(数值、字符串和布尔值,它们会被自动转成立即 resolved 的 Promise 对象)。
async
函数的返回值是 Promise 对象,可以用 then
方法指定下一步的操作。进一步说,async
函数完全可以看作多个异步操作,包装成的一个 Promise 对象,而 await
命令就是内部 then
命令的语法糖。
二、基本用法
(1)async
async
函数返回一个 Promise 对象,可以使用 then
方法添加回调函数。当函数执行的时候,一旦遇到 await
就会先返回,等到异步操作完成,再接着执行函数体内后面的语句。async
函数内部 return
语句返回的值,会成为 then
方法回调函数的参数。
async function f() {
return 'hello'
}
console.log(f()); // promise对象
f().then(result => {
console.log(result); // hello
})
async
函数内部抛出错误,会导致返回的 Promise 对象变为 rejec
t状态。抛出的错误对象会被 catch
方法回调函数接收到。
async function f() {
throw new Error('出错了')
}
f().then(result => {
console.log(result);
}).catch(err => {
console.log(err); // Uncaught (in promise) Error: 出错了
})
(2)await
正常情况下,await
命令后面是一个 Promise 对象,返回该对象的结果。如果不是 Promise 对象,就直接返回对应的值。另外,await
命令只能用在 async
函数之中,如果用在普通函数,就会报错。
async function f() {
// 等同于
// return 123;
return await 123;
}
f().then(v => console.log(v))
// 123
await
命令后面的 Promise 对象如果变为 reject
状态,则 reject
的参数会被 catch
方法的回调函数接收到。等同于async函数返回的 Promise 对象被reject。
async function f() {
await Promise.reject('出错了');
}
f()
.then(v => console.log(v))
.catch(e => console.log(e))
// 出错了
上面代码中,await语句前面没有return,但是reject方法的参数依然传入了catch方法的回调函数。这里如果在await前面加上return,效果是一样的。
任何一个await语句后面的 Promise 对象变为reject状态,那么整个async函数都会中断执行。
async function f() {
await Promise.reject('出错了');
await Promise.resolve('hello world'); // 不会执行
}
(3)使用注意事项
await
命令后面的 Promise对象,运行结果可能是 rejected
,所以最好把 await
命令放在 try...catch
代码块中。
async function myFunction() {
try {
await test();
} catch (err) {
console.log(err);
}
}
// 另一种写法
async function myFunction() {
await test().catch(function (err) {
console.log(err);
});
}
(4)案例
案例1:
async function f2() {
let promise = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('hello')
},1000)
})
// await 后应该是一个 Promise 对象,如果不是,会被转成一个 Promise 对象
// await必须配合 async 来使用
let result = await promise; // 一个表达式,表达式的值就是 promise 所返回的值
console.log(result);
console.log(await 4);
console.log(2);
return 3; // 相当于:return Promise.resolve(3)
}
f2().then(result => {
console.log(result);
})
// hello
// 4
// 2
// 3
案例2: 借助await命令就可以让程序停顿指定的时间,实现休眠效果。
function sleep(internal) {
return new Promise(resolve => {
setTimeout(resolve, internal);
})
}
async function f3() {
for (let i = 0; i < 5; i++) {
console.log(i);
await sleep(100);
}
}
f3();