关注前端小鱼,阅读更多原创技术文章。执行异步相关代码→异步函数ES8扩展了函数,增加了2个新关键字async和awaitasyncasync关键字用于声明异步函数,可以在函数声明、函数表达式、箭头函数和方法中使用asyncfunctionfoo(){}//在函数声明中使用letbar=asyncfunction(){}//在函数表达式中使用letbaz=async()=>{}//在箭头函数中使用classQux{asyncqux(){}//使用在methods}async关键字使函数异步,代码仍然是同步计算的,参数或闭包也有普通JS函数的正常行为asyncfunctionfoo(){console.log(1)}foo()console.log(2)/*1、foo()函数先被求值2*/异步函数return返回的值会被Promise.resolve()包装成一个合约对象,异步函数的调用总会返回合约对象如果return关键字返回一个实现了thenable接口的对象(callback,contract),它被提供给then()的处理程序解包如果return关键字返回一个常规值,则返回值被视为已解析futureAbout(无return关键字,返回值视为未定义)asyncfunctionfoo(){return'foo'//返回原值}console.log(foo())//Promise{:"foo"},被视为已解决的合约foo().then((result)=>console.log(result))//'foo'asyncfunctionbar2(){return['bar']//return不实现thenable接口对象}console.log(bar2())//Promise{:['bar']},被视为已解决的promisebar2().then((result)=>console.log(result))//['bar']asyncfunctionbaz2(){constthenable={then(callback){callback('baz')},}returnthenable//返回thenable实现Non-接口的合约对象}console.log(baz2())//Promise{}baz2().then((result)=>console.log(result))//'baz',bythen()unpackasyncfunctionqux(){returnPromise.resolve('qux')//返回解析后的合约}console.log(qux())//Promise{}qux().then((result)=>console.log(result))//'qux',由then()异步函数rejectQux(){returnPromise.reject('qux')//返回被拒绝的promise}console.log(rejectQux())//Promise{}rejectQux().then(null,(result)=>console.log(result))//'qux',被then()解包//未捕获(在承诺中)quxrejectQux().catch((result)=>console.log(result))//'qux',在被catch()展开的异步函数中抛出的错误将返回一个被拒绝的合约asyncfunctionfoo(){console.log(1)throw3}foo().catch((result)=>console.log(result))//向返回的合约添加拒绝处理程序console.log(2)/*1,foo()函数Evaluatedfirst23*/异步函数中拒绝合约的错误(不是“returnrejectionAbsolutepromise")不会被asyncfunctionasyncfunctionfoo(){Promise.reject(3)//rejectedpromise(notreturn)}foo().catch((result)=>console.log(result))//catch()方法抓不到//Uncaught(inpromise)3.浏览器消息队列捕获await,使用await关键字可以暂停异步函数代码的执行,等待期可以解决letp=newPromise((resolve,reject)=>{setTimeout(resolve,1000,3)})p.then((x)=>console.log(x))//3//重写异步函数foo()为async/await{letp=newPromise((resolve,reject)=>{setTimeout(resolve,1000,3)})console.log(awaitp)}foo()//3await将尝试解压对象(类似于yield),然后将值传递给表达式,然后异步恢复异步函数的执行asyncfunctionfoo(){console.log(awaitPromise.resolve('foo'))//unwrapthepromise,然后将值传递给表达式}foo()asyncfunctionbar2(){returnawaitPromise.resolve('bar')}bar2().then((res)=>console.log(res))//'bar'异步函数baz2(){awaitnewPromise((resolve,reject)=>{setTimeout(resolve,1000)})console.log('baz')}baz2()//'baz'(1000毫秒后)await根据等待值执行不同如果等待值是一个对象(回调,contract)实现了thenable接口,对象被await解包。如果等待值是正常值,则该值被视为已解决的期货合约(然后由awaittounwrap)asyncfunctionfoo(){console.log(await'foo')//等待原始值,被视为已解决的promisePromise.resolve('foo'),然后由await解包}foo()//'foo'asyncfunctionbar2(){console.log(await['bar'])//waitingvalue是一个没有实现thenable接口的对象,被当做一个resolvedcontract被await解包}bar2()//["bar"]asyncfunctionbaz2(){constthenable={then(callback){callback('baz')},}console.log(awaitthenable)//wait值实现了被await解包的thenable接口}baz2()//'baz'asyncfunctionqux(){console.log(awaitPromise.resolve('qux'))//等待值被解析promise}qux()//'qux'wait会抛出错误同步操作,返回一个被拒绝的合约asyncfunctionfoo(){console.log(1)await(()=>{throw3//抛出同步操作错误})()}foo().catch((result)=>console.log(result))//将拒绝处理程序添加到返回的合约console.log(2)/*123*/用于拒绝如果合约使用await,它会释放错误值(返回被拒绝的合约)asyncfunctionfoo(){console.log(1)awaitPromise.reject(3)//在拒绝合约,返回它(后续代码不会执行)console.log(4)//不执行}foo().catch((result)=>console.log(result))//添加拒绝处理程序返回的合约console.log(2)/*123*/awaitlimitmustbeinasync函数中使用的异步函数不能在顶级上下文中使用(如