什么是async
async的意思是“異步”,顧名思義就是有關異步操作的關鍵字,async 是 ES7 才有的,與我們之前說的Promise、Generator有很大的關聯。
使用語法:
async function name(param){
param //傳遞給函數的參數名稱
statements //函數體
}
name().then(function(res){
res//異步操作返回的結果
})
async 函數返回一個Promise對象,可以使用then方法添加回調函數。具體實例如下:
async function show(){ return {a:12,b:15} } console.log(show())//Promise {<fulfilled>: {…}} show().then(res=>{ console.log("res",res) })
什么是await
await關鍵字存在async函數表達式中,用於等待Promise對象,暫停執行,等到異步操作完成后,恢復async函數的執行並返回解析值。如果把await放在asnyc函數體外,會報語法錯誤。
使用語法:
asnyc function name(){
returnValue = await expression;
}
expression 是一個Promise對象或一個需要等待的值,針對所跟不同表達式,有兩種處理方式:
對於Promise對象,await會阻塞主函數執行,等待Promise對象執行resolve之后,resolve返回值作為await表達式運算結果,然后繼續向下執行。
對於非Promise對象,可以是字符串、布爾值、數值以及普通函數等。await直接返回對應的值,而不是等待其執行結果。
await等待Promise對象實例如下:
async function test1(){ console.log("執行") return new Promise((resolve,reject)=>{ setTimeout(()=>{ console.log("延遲3秒之后返回成功") resolve({a:'1'}) },3000) }) } async function test2(){ let x = await test1() console.log("x",x)//{a: "1"} return x } test2().then(function(res){ console.log("res",res)//{a: "1"} })
await 跟 普通函數 實例如下:
function test3(){ console.log("普通函數") } async function test4(){ await test3() console.log("直接執行") } test4()
捕獲異常
上述的await后跟Promise對象,我們知道Promise有兩種狀態,resolved() 和 rejected() ,如果Promise對象變為rejected,會如何處理?
function testAwait(){ return Promise.reject("error"); } async function test1(){ await testAwait(); console.log("test1");//沒有打印 } test1().then(v=>{ console.log(v); }).catch(e=>{ console.log(e);//"error" })
從上實例執行結果發現,返回的reject狀態被外層的catch捕獲,然后終止了后面的執行。但是在有些情況下,即使出錯了我們還是繼續執行,而不是中斷,此時我們借助try...catch捕獲內部異常。
function test1(){ return new Promise((resolve,reject)=>{ reject("error") }) } async function test2(){ try{ await test1() }catch(e){ console.log("報錯",e) } } test2().then((res)=>{ console.log("執行成功",res) // 打印:執行成功undefined }).catch(err=>{ console.log('err',err) })
Generator與async對比:
- async利用await阻塞原理,代替了Generator的 yield 。
- async 相比Generator 不需要 run 流程函數,完美地實現了異步流程。
從 Promise 到 Generator , 再到 async ,對於異步編程的解決方案越來越完美,這就是ES6不斷發展的魅力所在。