async 是“异步”的简写,而 await 可以认为是 async wait 的简写。
所以应该很好理解 async 用于声明一个 函数 是异步的,而 await 用于等待一个异步函数执行完成。
在函数前面加上async 关键字,来表示它是异步的,那怎么调用呢?async 函数也是函数,平时我们怎么使用函数就怎么使用它,直接加括号调用就可以了。
async function timeout() {
return 'hello world'
}
console.log(timeout()); //打印async函数执行后是什么值,这里的输出并不是它真的执行内部代码了
timeout().then( (data) => {
console.log(data);
});
console.log('虽然在后面,但是我先执行');
输出结果:
Promise {: “hello world”}
虽然在后面,但是我先执行
hello world
async 函数返回的是一个Promise 对象
,如果要获取到Promise 返回值,我们应该用then 方法或者catch方法(当Promise对象返回resolved状态之则调用then方法;async 函数内部抛出错误返回rejected状态则调用catch方法)。
async function timeout(flag) {
if (flag) {
return 'hello world'
} else {
throw 'my god, failure'
}
}
timeout(true).then(data => {
console.log(data)
})
timeout(false).catch(err => {
console.log(err)
})
输出结果:
hello world
my god, failure
await 可以用于等待一个 async 函数的返回值
——这也可以说是 await 在等 async 函数,但要清楚,它等的实际是一个返回值。注意到await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的
。
function getSomething() {
return "normal function";
}
async function testAsync() {
return Promise.resolve("async function");
}
async function test() {
const v1 = await getSomething(); // await后面跟普通函数
const v2 = await testAsync(); // await后面跟async函数
console.log(v1);
console.log(v2);
}
test();
//最后输出:
// normal function
// async function
如果await等到的是一个 Promise 对象,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。await 就忙起来了,它会阻塞后面的代码。这里的阻塞——就是 await 必须用在 async 函数中
的原因。async 函数调用不会造成阻塞,它内部所有的阻塞都被封装在一个 Promise 对象中异步执行。
// 2s 之后返回双倍的值
function doubleAfter2seconds(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2 * num)
}, 2000);
} )
// return Promise.resolve(2 * num);
}
async function testResult() {
let result = await doubleAfter2seconds(30);
console.log(result);
}
testResult(); // 2s之后,控制台输出 60
————————————————————————————————————
使用 ES7 的 async/await 时报错现象:
原因:这个regeneratorRuntime在浏览器上是不认识的,通过百度,需要安装一个babel-plugin-transform-runtime插件。
1、使用npm安装
npm i --save-dev babel-plugin-transform-runtime
2、然后在 .babelrc 文件中添加:
{
"plugins": [
[
"transform-runtime",
{
"helpers": false,
"polyfill": false,
"regenerator": true,
"moduleName": "babel-runtime"
}
]
]
}