ES6的async和await
async用于修饰内部有异步操作的函数,
async 定义的函数会默认的返回一个Promise对象resolve的值,因此对async函数可以直接进行then操作,返回的值即为then方法的传入函数
-
async的作用:将不是promise对象的返回值封装为resolved的promise并返回,如果没有返回值,则返回rejected的promise
-
await的作用:阻塞等待一个返回值,无所谓这个返回值是同步的还是异步的,是普通对象还是promise对象
await关键字只阻塞当前路径的代码
async
被async修饰的函数有何区别?
const test = function () {
return 1000
}
const testAysnc = async function () {
return 1000
}
const testAsync2 = async function () {}
console.log(‘test() :>> ‘, test());
console.log(‘testAysnc() :>> ‘, testAysnc())
console.log(‘testAsync2() :>> ‘, testAsync2());
可以看出,async函数将返回值封装成了一个fulfilled状态的promise对象,无论其返回值如何
await
试试看
function getB() {
setTimeout(() => {
return 2
}, 2000)
}
function getC() {
setTimeout(() => {
return 3
}, 3000)
}
async function steps() {
const a = await 1;
console.log(‘a :>> ‘, a);
const b = await getB();
console.log(‘b :>> ‘, b);
const c = await getC();
console.log(‘c :>> ‘, c);
}
steps()
结果:直接返回1 undefined undefined
如果函数没有返回promise对象,那么await会将其当做同步来操作,即便内部是异步的
利用await结合promise对象,我们可以将异步的步骤当做同步来使用
如,当abc都加载完成后,再打印这三个数:
function getB() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 2000)
})
}
function getC() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000)
})
}
async function steps() {
const a = 1;
const b = await getB();
const c = await getC();
console.log(‘a :>> ‘, a);
console.log(‘b :>> ‘, b);
console.log(‘c :>> ‘, c);
}
结果为:0+2+3=5秒后,输出1 2 3
又或者,abc顺次打印,前一个数不打印出来,后一个数不能打印
function getB() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(2)
}, 2000)
})
}
function getC() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(3)
}, 3000)
})
}
async function steps() {
const a = await 1;
console.log(‘a :>> ‘, a);
const b = await getB();
console.log(‘b :>> ‘, b);
const c = await getC();
console.log(‘c :>> ‘, c);
}
steps()
结果为:立即打印1,两秒后打印2,三秒后打印3
综合应用
使用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);
}
function work() {
console.time(‘work‘)
const time1 = 300;
step1(time1)
.then(time2 => {
return step2(time2)
})
.then(time3 => {
return step3(time3)
})
.then(result => {
console.log(`你最终挣了${result}`);
console.timeEnd("work");
})
}
work()
结果:
使用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(n) {
console.log(`step2 with ${n}`);
return takeLongTime(n);
}
function step3(n) {
console.log(`step3 with ${n}`);
return takeLongTime(n);
}
async function work() {
console.time(‘work‘)
const time1 = await step1(300)
const time2 = await step2(time1)
const time3 = await step3(time2)
console.log(`你最终挣了${time3}`);
console.timeEnd("work");
}
work()
当然,结果是一样的