目录
1. 解释async和await
- async是异步的简写,用于声明一个函数是异步执行。await用于等待一个异步方法执行完毕。
- await只能用于async函数中
2.async的作用
async输出的是一个 Promise 对象,如图我们测试一下。
async function test()
{
return 123;
}
console.log(test());
结果如下:如果在函数中 return
一个直接量,async 会把这个直接量通过 Promise.resolve()
封装成 Promise 对象。
Promise {<fulfilled>: 123}
async 函数返回的是一个 Promise 对象,所以在最外层不能用 await 获取其返回值的情况下,我们当然应该用原来的方式:then()
链来处理这个 Promise 对象。
async function test()
{
return 123;
}
// console.log(test());
test().then(res=>{
console.log(res) ///输出123
})
Promise 的特点——无等待,所以在没有 await
的情况下执行 async 函数,它会立即执行,返回一个 Promise 对象,并且不会阻塞后面的语句。
3. await等待
因为 async 函数返回一个 Promise 对象,所以 await 可以用于等待一个 async 函数的返回值——这也可以说是 await 在等 async 函数,但要清楚,它等的实际是一个返回值。注意到 await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。
function index() {
return "我是直接变量";
}
async function indexAsync() {
return Promise.resolve("我是promise对象");
}
async function test() {
const v1 = await index();
const v2 = await indexAsync();
console.log(v1, v2);
}
test();
结果如下,验证了以上两种均可用await
我是直接变量 我是promise对象
4.await到底能干啥
await 等到了它要等的东西,一个 Promise 对象,或者其它值,然后呢?await
是个运算符,用于组成表达式,await 表达式的运算结果取决于它等的东西。
如果它等到的不是一个 Promise 对象,那 await 表达式的运算结果就是它等到的东西。如果它等到的是一个 Promise 对象,它会阻塞后面的代码,等着 Promise 对象 resolve,然后得到 resolve 的值,作为 await 表达式的运算结果。
使用await计算和,最终的输出结果为80,也就是说await等待函数执行完毕才会继续往下走。
async function indexAsync(x) {
return Promise.resolve(x + 20);
}
async function test() {
const a = await indexAsync(20);
const b = await indexAsync(a);
const c = await indexAsync(b);
console.log(c);
}
test();
在回调函数中使用await,回调函数必须使用async才可否则会报错
Can not use keyword 'await' outside an async function
function index() {
return new Promise(function(reslove, reject) {
reslove("我是返回结果");
})
}
async function indexAsync(x) {
return Promise.resolve(x + 20);
}
function test() {
index().then(async res => {
console.log(res)
const a = await indexAsync(20);
const b = await indexAsync(a);
const c = await indexAsync(b);
console.log(c);
})
}
test();
假设一个业务,分多个步骤完成,每个步骤都是异步的,而且依赖于上一个步骤的结果。使用Promise写为如下。
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n + 200), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(m, n) {
console.log(`step2 with ${m} and ${n}`);
return takeLongTime(m + n);
}
function step3(k, m, n) {
console.log(`step3 with ${k}, ${m} and ${n}`);
return takeLongTime(k + m + n);
}
function index() {
const time1 = 300;
step1(time1)
.then(time2 => {
return step2(time1, time2)
.then(time3 => [time1, time2, time3]);
})
.then(times => {
const [time1, time2, time3] = times;
return step3(time1, time2, time3);
})
.then(result => {
console.log(`result is ${result}`);
console.timeEnd("doIt");
});
}
index();
使用await写如下代码
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => resolve(n + 200), n);
});
}
function step1(n) {
console.log(`step1 with ${n}`);
return takeLongTime(n);
}
function step2(m, n) {
console.log(`step2 with ${m} and ${n}`);
return takeLongTime(m + n);
}
function step3(k, m, n) {
console.log(`step3 with ${k}, ${m} and ${n}`);
return takeLongTime(k + m + n);
}
async function index() {
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time1, time2);
const result = await step3(time1, time2, time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
index();
结果如下