1. async和await最关键的用途是以同步的写法实现了异步调用,是对Generator异步方法的简化和改进。使用Generator实现异步的缺点如下:
- 得有一个任务执行器来自动调用next()
yield
命令后面只能是 Thunk 函数或 Promise 对象,Thunk函数只接受一个参数,然后返回一个把回调函数作为参数的函数(很绕,不直观)
2.函数前使用async修饰符时不管函数内出不出错都会返回一个Promise对象;
3.返回的Promise对象是由谁决定的?
- 如果函数体内的语句没有错误,则会返回一个fulfilled状态的Promise,否则返回一个rejected状态的Promise
- 如果有await语句,只要其中一个await后面的语句出错,则返回一个rejected状态的Promise,后面的语句不会被执行。
function test(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ reject('出错了') },500) }) } async function f() { await test(); console.log('上面的await返回了rejected状态') await Promise.resolve(456); } f().then(v => console.log(v)).catch(e => console.log('有错误'))
在上面的代码中f函数语句内await test()下面的语句都不会被执行。
- 如果返回fulfilled状态的Promise对象,可以使用return xxx语句指定值,不然默认为undefined
function test(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve('出错了') },500) }) } async function f() { await test(); await Promise.resolve(456); return '返回值' } f().then(v => console.log(v)).catch(e => console.log('有错误'))
控制台输出“返回值”,如果注释掉f函数里面的return语句,控制台将输出undefined
4.await后面的代码会返回什么?
await后面的代码可以是同步代码,也可以是异步代码,相应的情况如下:
//同步函数 function syncFun(){ } //异步函数 function asyncFun(){ return new Promise((resolve,reject)=>{ setTimeout(()=>{ resolve(456) },1000) }) } async function f() { let a=await 123; //a为123 let b=await syncFun(); //b为undefined let c=await asyncFun() //c为456 return '返回值' } f().then(v => console.log(v)).catch(e => console.log(e))
如果await后面是一个函数(不管是同步还是异步的),只要有错误或者异步返回的状态是rejected,则马上中止此await下面的语句,并返回一个rejected状态的Promise