es6的async, await使用方法及执行机制
async/await其实就是promise和generator的语法糖:
async function demo01() {
console.log(1)
return ‘demo1’;
}
demo01().then(function(a){
console.log(a)
});
输出结果为1,demo1
async用来表示函数是异步的,定义的函数会返回一个promise对象,可以使用then方法添加回调函数。上列代码中的async函数中的console.log(1)可以当一个同步的队列执行,也就是说但你在定义async function的时候 里面的代码是以同步的方式执行,只不过async的返回是一个promise,可以用.then()的方式去执行回调,如同上述内容。若 async 定义的函数有返回值,return ‘demo1’;相当于Promise.resolve('demo1’),没有声明式的 return则相当于执行了Promise.resolve();
await是和async一起来使用:
async function demo2(){
console.log(7)
await a()
console.log(6)
}
demo2()
function a() {
console.log(‘demo2’)
}
await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。如果await的是 promise对象会造成异步函数停止执行并且等待 promise 的解决,如果等的是正常的表达式则立即执行。
当他和promise一起用的话:
async function demo2(){
console.log(7)
await a()
await new Promise(function(resolve, reject){
console.log(1)
resolve(‘promise’)
})
console.log(6)
}
demo2()
function a() {
console.log(‘demo2’)
}
上述的代码中返回的结果是 7,demo2,1,6。仔细观察是不感觉await和generator的用法很像。同时在用await返回promise的时候,他会默认直接执行promise的resolve,并将其加入微任务队列。
在错误处理的时候需要用try catch来实现:
function sleep(second) {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject('want to sleep~');
}, second);
})
}
async function errorDemo() {
let result = await sleep(1000);
console.log(result);
}
errorDemo();// VM706:11 Uncaught (in promise) want to sleep~
// 为了处理Promise.reject 的情况我们应该将代码块用 try catch 包裹一下
async function errorDemoSuper() {
try {
let result = await sleep(1000);
console.log(result);
} catch (err) {
console.log(err);
}
}
errorDemoSuper();// want to sleep~
// 有了 try catch 之后我们就能够拿到 Promise.reject 回来的数据了。
还有个例子:
a()
async function a(){
console.log(1)
await new Promise(function(resolve, reject) {
setTimeout(()=>{
resolve(3)
},500)
}).then((e)=>{
console.log(e)
})
console.log(2)
}
上述代码返回如下:
通俗一点:个人理解就是在async函数中使用await的时候,同时await后面是跟着promise时,会把await的结果作为同步去执行(也就是阻塞了await下面的代码,如上文提到的 “ 如果await的是 promise对象会造成异步函数停止执行并且等待 promise 的解决 ”),所以不管await后面的promise中,里面是同步代码还是settimeout或者ajax,都会先把它执行完毕,然后在去执行await后面的代码(也就是下一部分代码 )
面试题
async function demo01() {
console.log(1)
return 'demo1';
}
console.log('0')
demo01().then(function(a){
console.log(a)
});
console.log('8')
async function demo2(){
console.log(7)
await a()
console.log(6)
}
demo2()
let promise = new Promise(function(resolve, reject){
resolve(5)
console.log(3)
setTimeout(function(){console.log(4)})
})
console.log(2)
promise.then(function(a){
console.log(a)
})
function a(){
console.log('demo2')
}
结果为