fn()
。进一步说,async函数彻底能够看做多个异步操做,包装成的一个Promise对象,而await命令就是then方法的语法糖promise
async函数返回一个Promise对象,可使用then方法添加回调函数。当函数执行的时候,一旦遇到await就会先返回,等到异步操做完成,在接着执行函数体后面的语句异步
async function fn(){ console.log(4) let f1 = await Promise.resolve(1) console.log(f1) // 1 let f2 = await Promise.resolve(2) return f2 } fn().then(res=>{ console.log(res) // 2 }) console.log(3) // 4 3 1 2
上面代码中,函数前面的async关键字,表示函数内部有异步操做。调用该函数时,会当即返回一个Promise对象。async
function timeout(ms){ return new Promise((resolve)=>{ setTimeout(resolve,ms) }) } async function fn(value,ms){ await timeout(ms) console.log(value) } fn('haha',3000)
上面代码会在3秒后输出
haha
函数
async函数有多种使用形式。this
// 函数声明 async function fn(){} // 函数表达式 let fn1 = async function(){} // 对象的方法 let obj = {async foo(){}} obj.foo().then(()=>console.log(111)) // 111 // class 的方法 class fn2{ constructor(name){ this.name = name; } async getName(){ return this.name } } let name = new fn2('小明'); name.getName().then(res=>console.log(res)) // 小明
async函数返回一个Pormise对象。
async函数内部return语句返回的值,会成为then
方法回调函数的参数code
let fn = async function(){ return 111 } fn().then(res=>{console.log(res)}) // 111
上面代码,函数
fn
返回的值,会被then
放回回调函数接收到orm
async内部抛出错误,会致使返回的Promise对象变为reject状态。抛出的错误对象会被catch方法回调函数接收到。对象
let fn = async function(){ throw new Error('出错了') } fn().catch(error=>{ console.log(error); // Error: 出错了 })
async函数返回的Promise对象,碧玺等到内部全部await命令后面的Promise对象执行完,才会发生状态改变,除非遇到return
语句或者抛出错误。也就是说,只有asunc函数内部的异步操做执行完,才会执行then方法指定的回调函数。字符串
let fn = async function(){ await new Promise((resolve)=>{ setTimeout(resolve,3000) }) await new Promise((resolve)=>{ setTimeout(resolve,3000) }) return 1 } fn().then(res=>{ console.log(res); })
上面代码,
then
回调函数会在6秒以后输出res
get
正常状况下,await命令后面是一个Promise对象,返回该对象的结果。若是不是Promise对象,就直接返回对应的值
let fn = async function(){ // 等同于 // return 1 return await 1 } fn().then(res=>{ console.log(res); // 1 })
上面代码中,await命令的参数是数值1,这是等同于
return 1
let fn = async ()=>{ await Promise.reject('出错了') } fn().catch(error=>{console.log(error)}) // 出错了
注意:上面代码中,await语句前面没有
return
,可是reject
方法的参数依然传入了catch方法的回调函数。这里若是在await前面加上return,效果是同样的
注意:任何一个await语句后面的Promise对象变为reject,那么整个async函数都会中断执行
有时,咱们但愿即便前一个异步操做失败,也不要中断后面的异步操做。这时能够将第一个await放在try...catch结构里面,这样无论这个异步操做是否成功,第二个await都会执行
let fn = async ()=>{ try{ await Promise.reject('出错了') }catch(error){ console.log(error) } return 1 } fn().then(res=>console.log(res)) // 1
另外一种写法
let fn = async ()=>{ await Promise.reject('出错了').catch(error=>{ console.log(error) }) return 1 } fn().then(res=>console.log(res)) // 1
若是await后面的异步操做出错,那么等同于async函数返回的 Promise 对象被reject。
let fn = async ()=>{ await Promise.reject('出错了') return 1 } fn() .then(res=>console.log(res)) .catch(error=>{ console.log(error) // 出错了 })
上面代码中,函数fn执行后,await后面的Promise对象抛出了一个错误对象,致使catca方法的回调函数被调用。
防止出错的方法,也是将其放在try...catch
代码块中
let fn = async ()=>{ try{ await Promise.reject('出错了') }catch(error){ console.log(error); } return 1 } fn() .then(res=>console.log(res)) // 1
若是有多个await命令,能够统一放在try...catch
中