async与await的那些事儿

async/await是ES7中提出的基于Promise的解决异步的方案.

我们先看看async的用法吧.其实用法很简单的,就是在函数前加上async,来表达出它是一个异步函数.异步函数,也就意味着他不会造成后面执行的代码的堵塞,我们来写一个简单的async函数看看:

async function theme(){
return "ljy";
}

调用这个函数也十分简单,就像是平常对同步函数一样,直接后面(),我们可以再跟一个同步函数对比下哈:

async function theme(){
return "ljy";
}
theme();
console.log('我是下面的代码')

那么,运行出来的结果为:

我们运行后却发现,而theme()后,并未有任何输出,我们把上述代码,再修改下看看:

async function theme(){
return "ljy";
}
console.log(theme());
console.log('我是下面的代码')

这样可以看的很明显了,原来async函数返回的是一个promise对象,那如果我们想要获取到promise的返回值,我们就可以使用then()来得到了.

async function theme(){
return "ljy";
}
theme().then(boo=>{
console.log(boo)
})
console.log('我是下面的代码')

这样成功执行了theme函数,且得到了其中的值,并且之后的代码也顺利执行了。回过头我们看前面,在console.log(theme())的时候,我们发现它的状态为fufilled,这实际上是async函数内部的实现原理。若async函数中返回一个值,那么内部会调用Promise.resolve(),将他转换成一个promise对象作为返回,但如果theme函数内部报错了呢.就会调用Promise.reject()来返回一个promise对象:

async function theme(boo){
if(boo){
return "ljy";}
else{
throw "bad bad"
}
}
console.log(theme(true));//调用Promise.resolve().返回promise对象
console.log(theme(false));//调用Promise.reject().返回promise对象

若函数内部抛出错误,promise对象有一个catch方式进行捕获.

theme(false).catch(err=>{
console.log(err)
})

async的话,函数内自带了执行器,无需手动next(),也有更好的语义,async就是直接表示函数里有异步操作,await紧跟在后面的表达式需要等待结果,而且适用性也更广,yield命令后面只能是Thunk函数或Promise对象,而async函数的await命令后面,可以是Promise对象或者原始类型的值(这些都会自动转成立即resolved的Promise对象),且返回值如上所述是Promise对象,比Generator函数返回的Iterator对象方便,可以直接使用then()方法进行调用.

那么,我们接下来看看await吧~await之后可以放任何表达式,但是我们大部分时候,放的是一个返回promise对象的表达式

下面,我们来看个例子:

function double(num){
return new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(num+7)},3000)
})
}
async function test(){
let final= await double(22);
console.log(final)
}
test();

我们看到结果,调用了test函数,它其中有await,那么代码就暂停到这里了,等double(22)执行完毕后,double(22)中的promise开始执行,3秒后,promise resolve,并返回29,这时候await就拿到了返回值29,并赋值给final.

那我们再试试多个数的:

function double(num){
return new Promise((resolve,reject)=>{
setTimeout(()=>{resolve(num+7)},3000)
})
}
async function test(){
let lee=await double(17);
let gene=await double(27);
let yee=await double(77);
console.log(lee + gene +yee)
}
test()

9秒后,控制台就会输出结果142,这样写异步函数就像是在写同步函数一样,非常OK。

原文地址:https://www.cnblogs.com/ljylearnsmore/p/14533548.html