async、await是promise的語法糖,使用async和await,可讓異步代碼的書寫像同步代碼同樣。promise
將async關鍵字放在一個普通的function前面,會變成async function,那麼async function和普通的function有什麼不同呢?異步
function hello() { return 'hello' } hello() // "hello"
async function hello() { return 'hello' } hello() // Promise {<fulfilled>: "hello"}
從上面的列子能夠看出來,當在function 前面加上async後,該函數就會返回一個promise。
異步函數的特徵之一就是保證函數的返回值是promiseasync
由於async function的返回值是一個promise,要使用promise完成時的返回值,能夠經過.then()進行獲取函數
async function hello() { return 'hello' } hello().then((str) => alert(str))
await關鍵字須要和async關鍵字配合使用,也只能在異步函數中才會起做用。await能夠放在任何異步的,基於promise的函數以前,它會阻塞代碼的執行,知道promise完成,而後返回返回結果值。code
async function hello() { return new Promise((resolve) => { setTimeout(() => {resolve('hello')}, 1000); }); } async function sayHello() { await hello(); alert('done!') } sayHello(); // Promise {<pending>}
1s後會彈出「done!」ip
Q1:上面說到await會阻塞程序運行,直到異步函數hello()執行出結果,那麼若是hello執行的結果是reject或者因爲一些問題throw new Error()的話,await後面的代碼還會執行嗎?
答案:不能執行。get
async function hello() { return new Promise((resolve, reject) => { reject('hello'); }); } async function sayHello() { await hello(); alert('done!') } sayHello(); // Promise {<rejected>: "hello"}
async function hello() { return new Promise((resolve, reject) => { throw new Error('hello'); }); } async function sayHello() { await hello(); alert('done!') } sayHello(); // Promise {<rejected>: Error: hello at <anonymous>:3:11 at new Promise (<anonymous>) at hello (<anonymous>:2:1…}
這兩個狀況下都不會在執行 alert('done!');同步
若是咱們但願hello()運行中執行了reject或者是拋出錯誤後,不影響後面alert('hello')
的執行應該怎麼辦?增長try catch就行it
async function sayHello() { try { await hello(); } catch (e) { console.log(e) } alert('done!') }
Q2:reject或者throw new error的捕獲會繼續向下傳遞嗎?
答案:會,reject和error會一直冒泡出去io
async function hello() { return new Promise((resolve, reject) => { throw new Error('hello'); }); } async function sayHello() { await hello(); alert('done!') } sayHello().then((res) => {alert(res), (rej)=>{alert(rej)}}) // Promise {<fulfilled>: undefined}
窗口會彈出「Error: hello」,reject同理,輸出「hello」
async function hello() { return new Promise((resolve, reject) => { throw new Error('hello'); }); } async function sayHello() { await hello(); alert('done!') } async function catchFunc() { try { await sayHello() } catch(e) { alert(e) } } catchFunc() // Promise {<fulfilled>: undefined}
窗口會彈出「Error: hello」,reject同理,輸出「hello」
Q3:下面兩段代碼有什麼區別
代碼片斷1
async function hello() { return new Promise((resolve, reject) => { throw new Error('hello'); }); } async function sayHello() { await hello(); alert('done!') } async function catchFunc() { try { sayHello() } catch(e) { alert(e) } } catchFunc() // Promise {<fulfilled>: undefined}
代碼片斷2:
async function hello() { return new Promise((resolve, reject) => { throw new Error('hello'); }); } async function sayHello() { await hello(); alert('done!') } async function catchFunc() { try { await sayHello() } catch(e) { alert(e) } } catchFunc() // Promise {<fulfilled>: undefined}
答案:代碼片斷2會彈出「Error:hello」,代碼片斷1不會。分析的緣由應該是代碼片斷2是在sayHello函數執行完後進行捕獲錯誤,因此能夠捕獲到錯誤,代碼片斷1沒有使用await,捕獲錯誤的時候函數sayHello異步執行還沒報錯,因此不會捕獲到。
未完待續...
既然async/await是promise的語法糖,兩者怎麼轉換呢?