目录
async异步函数
1.含义
2.用async+await来简化Generator函数
3.async函数特点+好处 (!重点)
a. 内置执行器
b. 更好的语义
c. 更广的适用性
注意:await命令后面接失败态的Promise对象会终端报错
注意:async内部函数是按照同步的方式进行执行的
d. 返回值是Promise对象
4.async函数的错误捕获(借助js的try-catch语句块)
5.async函数的应用
注:async函数对内同步,对外异步
es2017标准引入async函数,使异步操作变得更方便。
async函数是Gentertor函数的语法糖。
需求:每间隔1s按照需求输出1,2,3,4,5
Genderator函数:
//Promise封装延迟函数
const delay = n =>new Promise(resolve =>{
setTimeout(()=>{
resolve(n)
},1000)
})
//生成器函数
function * g(){
for(let i = 1;i<=5;i++){
const x = yield delay(i)
console.log(x)
}
}
//Genderator函数的执行必须依靠执行器,因此需要封装co模块
function co(g){
const o = g()
next()
function next(a){
const {value,done} = o.next(a)
if(done) return
value.then(data=>{
next(data)
})
}
}
co(g)
async+await函数:
//Promise封装延迟函数
const delay = n =>new Promise(resolve =>{
setTimeout(()=>{
resolve(n)
},1000)
})
//async异步函数
async function g(){
for(let i = 1;i<=5;i++){
const x = await delay(i) //await异步等待
console.log(x)
}
}
//调用异步函数
g()
async函数的执行,与普通函数一样(用同步的方式编写异步代码,可读性强)
async内置执行器,Genderator需要手动写co执行器函数
async和await,比起*和yiled,语义更清楚
async表示函数里面有异步操作,
await表示紧跟在后面的表达式需要等待结果
co模块约定,yield命令后面只能是Promise对象
而async函数的await命令后面,可以是Promise对象和原始类型的值
(数值、字符串和布尔值,成功态的Promise对象)
成功态
const fn = async() => {
const n = await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("success")
},2000)
})
console.log(n)
}
2s后输出:success
失败态
const fn = async() => {
const n = await new Promise((resolve,reject)=>{
setTimeout(()=>{
reject("fail")
},2000)
})
console.log(n)
}
中断报错
const fn = async() => {
console.log("111")
const n = await new Promise((resolve,reject)=>{
setTimeout(()=>{
resolve("success")
},2000)
})
console.log(n)
console.log("222")
}
输出:111=>2s后输出 success 222
async函数完全可以看作多个异步操作,包装成的一个Promise对象,
而await命令就是内部then命令简化的语法糖。
const f = () =>{ }
console.log(f())
输出:undefined
const f =async () =>{ }
console.log(f())
输出:Promise对象
const f =async () =>{
return “冰墩墩”
}
f().then(resolve=>{
console.log(resolve)
})
输出:冰墩墩
注:await不能提取reject的结果,需要进行手动捕获
await后面跟的是成功态的Promise实例时,await会自动提取到resolve中结果返回
如果await后面的Promise是失败态的,那么代码执行就会中断,要杜绝这种操作
即:await不能提取reject的结果,这时我们就需要手动捕获错误,借助js的try-catch语句块
成功态:
const fn = async() =>{
console.log(111);
try{const n = await new Promise((resolve,reject)=>{
setTimeout(()=>{resolve("success")
},2000)
})
console.log(n);
console.log(222)
}catch(e){
console.log("catch",e)
}
}
fn()
输出:111=>2s后 success 222
失败态:
const fn = async() =>{
console.log(111);
try{const n = await new Promise((resolve,reject)=>{
setTimeout(()=>{resolve("fail")
},2000)
})
console.log(n);
console.log(222)
}catch(e){
console.log("catch",e)
}
console.log(333)
}
fn()
输出:111=>2s后 catch fail 和 333
async函数 + await关键字 + Promise 三者配合使用
需求:完成做菜过程,每个环节的时间不等
function doDish(step){
return new Promis((resolve)=>{
setTimeout(()=>{
resolve(step)
},2000*Math.random()) // Math.random()是一个0~1的随机数
})
}
async function f(){
await step1 = doDish("买菜")
console.log(step1)
await step1 = doDish("洗菜")
console.log(step1)
await step1 = doDish("切菜")
console.log(step1)
await step1 = doDish("炒菜")
console.log(step1)
console.log(“结束”)
}
console.log(111)
f()
console.log(222)
输出:111=>222=>{买菜,洗菜,切菜,炒菜,结束}