异步编程async/await
async和await在干什么?
async声明一个函数是异步的,async声明的函数返回值是promise对象。
await只能用在async声明的函数内部,用于等待一个异步方法执行完成。
async的作用
async函数返回的是一个promise对象,在最外层又不能使用await去等待获取其返回值的情况下,我们只能用原来的promise方法then来处理:
async function test() {
return '123';
}
console.log(test()); // Promise {"123"}
test().then(v => {
console.log(v); // 123
})
promise的特点——无等待。所以在没有await的情况下,它会立即执行,返回一个promise对象,并且绝对不会阻塞后面的语句。这和普通的promise对象的函数没有任何区别。
所以关键在await。
await的作用
await等待的是一个表达式,这个表达式的计算结果是Promise对象或者其他值。
function test1() {
return '123';
}
async function test2() {
return '456';
}
async function run() {
const t1 = await test1();
const t2 = await test2();
console.log(t1, t2);
}
run(); // 123 456
如果await等待到的不是Promise对象,那么await表达式的运算结果就是它等到的东西,例如上述代码await test1()等到的是'123'。
如果await等待到的是Promise对象,那么它会阻塞后面的代码,等着Promise对象resolve,然后得到resolve的值,作为await的运算结果。
这里的阻塞,正是await为什么只能在async函数内部使用的原因。因为async函数不会造成阻塞,所以外部的代码依旧正常执行。所以阻塞仅仅只是async函数内部的阻塞。
async/await 的优势在于处理 then 链
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(n) {
console.log(`step2 with ${n}`);
return takeLongTime(n);
}
function step3(n) {
console.log(`step3 with ${n}`);
return takeLongTime(n);
}
使用then处理:
function doIt() {
console.time("doIt");
const time1 = 300;
step1(time1)
.then(time2 => step2(time2))
.then(time3 => step3(time3))
.then(result => {
console.log(`result is ${result}`);
console.timeEnd("doIt");
});
}
doIt();
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 2365.155029296875 ms
使用async/await处理:
async function doIt() {
console.time("doIt");
const time1 = 300;
const time2 = await step1(time1);
const time3 = await step2(time2);
const result = await step3(time3);
console.log(`result is ${result}`);
console.timeEnd("doIt");
}
doIt();
// step1 with 300
// step2 with 500
// step3 with 700
// result is 900
// doIt: 3106.3837890625 ms
参考文章:https://blog.csdn.net/MrWangJB/article/details/107881183