异步代码的处理方案
// 模拟请求function request(url){return new Promise((resolve,reject)=>{setTimeout(()=>{resolve(url)},2000);})}/* 方案一:多次回调 */// 回调地狱request('aaa').then(res=>{request(res+'bbb').then(res=>{request(res+'ccc').then(res=>{console.log(res)}})})/* 方案二:Promise中then的返回值来解决 */// 阅读性差,需要对每段代码块都需阅读request('aaa').then(res=>{return request(res+'bbb')}).then(res=>{return request(res+'ccc')}).then(res=>{console.log(res)})/* 方案三:Promise+Generator */function* getData(){const res1=yield request('aaa')const res2=yield request(res1+'bbb')const res3=yield request(res2+'ccc')console.log(res3)}// 手动调用const generator=getData()generator.next().value.then(res1=>{generator.next(res1).value.then(res2=>{generator.next(res2).value.then(res3=>{generator.next(res3)})})})// 自动调用/* execGenerator函数早在14-16年TJ就开源于github上,库名叫co */function execGenerator(genFn){const generator=genFn()return exec();function exec(res){const result=generator.then(res)// 结束if(result.done){return result.value}// 递归result.value.then(res=>exec(res))}}execGenerator(getData)/* 方案四:async-await */// 实质是Promise+Generator语法糖async function getData(){const res1=await request('aaa');const res2=await request('bbb');const res3=await request('ccc');console.log(res3)}
异步函数 async-await
本质是Promise+Generator语法糖
async(asynchronous):异步、非同步
sync(synchronous):同步、同时
定义异步函数
async function foo(){···}const bar=async()=>{···}class Person{async foo(){···}}
与同步函数的区别
1.返回值
异步函数的返回值一定是一个Promise对象
async function foo(){// 1.返回普通值return 123// 2.返回promisereturn new Promise((resolve,reject)=>{resolve(123)})// 3.返回thenablereturn {then(resolve,reject){resolve(123)}}}foo().then(res=>{console.log(res) // 123})
2.异常
async function foo(){console.log('async start')throw new Error('errorMsg')console.log('async end')}console.log('sync start')foo()console.log('sync end')/*sync startasync startsync endUncaught (in promise) Error: errorMsg*/
await关键字
1.await+表达式
表达式同Promise返回值,分三种情况
async function foo(){/* 情况一:普通值 */const res1 = await 123console.log(res2) // 123/* 情况二:Promise*/const res2 = await new Promise((resolve,reject)=>{resolve(345)})console.log(res2) // 345/* 情况三:thenable */const res3=await {then(reslove,reject){resolve(789)}}console.log(res3) // 789}
2.reject捕获
async function foo(){await new Promise(resolve,reject){reject('errorMsg')}}foo().catch(err=>console.log(err))
