閱讀目錄html
既然有了promise 爲何還要有async await ? 固然是promise 也不是完美的異步解決方案,而 async await 的寫法看起來更加簡單且容易理解。vue
Promise 對象用於表示一個異步操做的最終狀態(完成或失敗),以及其返回的值。ajax
Promise
對象是由關鍵字 new
及其構造函數來建立的。構造函數會,把一個叫作「處理器函數」(executor function)的函數做爲它的參數。這個「處理器函數」接受兩個函數resolve
和 reject
做爲其參數。當異步任務順利完成且返回結果值時,會調用 resolve
函數,而當異步任務失敗且返回失敗緣由(一般是一個錯誤對象)時,會調用reject
函數。vuex
promise 狀態api
pending:初始狀態,既不是成功,也不是失敗狀態
fulfilled:操做成功
rejected:操做失敗promise
1 var promise1 = new Promise(function(resolve, reject) { 2 setTimeout(function() { 3 resolve('foo'); 4 }, 300); 5 }); 6 promise1.then(function(value) { 7 console.log(value); 8 // foo 9 }); 10 console.log(promise1); 11 // [object Promise]
經過外部then() 方法來綁定成功、失敗的回調函數,有沒有感受這個跟以前的ajax 差很少,只不過是咱們把回調丟到了then() 中,這個then 而且支持鏈式操做,即若是存在多個嵌套那麼也就是不斷的then()。異步
先從字面意思來理解,async 是「異步」的意思,而 await 是等待的意思。因此應該很好理解 async 用於申明一個 異步的function(其實是async function 對象),而 await 用於等待一個異步任務執行完成的的結果。async
而且 await 只能出如今 async 函數中。函數
1 在api中,把結果return 出去 2 export async function getRetailUnitPrice () { 3 const reqBody = await get('/race/spot/racespot/enter/dayahead') 4 return reqBody 5 }
1 vuex 中把結果commit: 2 // 發電:日前機組中標出力 3 async getRealTimeRetailUnitPrice ({commit}) { 4 const {output} = await getRetailUnitPrice() 5 commit(types.PLANT_REALTIME_DAYAHEAD, {output}) 6 }
1 在vue中代碼 2 try {this.$store.dispatch('getRealTimeRetailUnitPrice') 3 } catch (e) { 4 this.$Message.error(e) 5 }
async 告訴程序這是一個異步操做,await 是一個操做符,即 await 後面是一個表達式。this
async 的返回值
1 // async 2 async function testAsync() { 3 return "hello async"; 4 } 5 const data = testAsync(); 6 console.log(data);
如圖所示:
當調用一個 async 函數時,會返回一個 Promise 對象。根據mdn的解釋
當這個 async 函數返回一個值時,Promise 的 resolve 方法會負責傳遞這個值;
當 async 函數拋出異常時,Promise 的 reject 方法也會傳遞這個異常值。async 函數中可能會有 await 表達式,await表達式會使 async 函數暫停執行,直到表達式中的 Promise 解析完成後繼續 執行 async中await 後面的代碼並返回解決結果。
注意, await 關鍵字僅僅在 async function中有效
既然返回的是Promise 對象,因此在最外層不能用 await 獲取其返回值的狀況下,那麼確定能夠用原來的方式:then() 鏈來處理這個 Promise 對象 如
1 // async 2 async function testAsync() { 3 return "hello async"; 4 } 5 let data = testAsync().then( (data) => { 6 console.log(data) // hello async 7 return data 8 }); 9 console.log(data);
若是 async 函數沒有返回值,又怎麼樣呢?很容易想到,它會返回 Promise.resolve(undefined)。
聯想一下 Promise 的特色無等待,因此在沒有 await 的狀況下執行 async 函數,它會當即執行,返回一個 Promise 對象,而且,毫不會阻塞後面的語句。
MDN 是這樣描述 await 的:
await 表達式會暫停當前 async function 的執行,等待 Promise 處理完成。若 Promise 正常處理(fulfilled),其回調的resolve函數參數做爲 await 表達式的值,繼續執行async function。若 Promise 處理異常(rejected),await 表達式會把 Promise 的異常緣由拋出。另外,若是 await 操做符後的表達式的值不是一個 Promise,則返回該值自己。
阮一峯老師的解釋我以爲更容易理解:
async 函數返回一個 Promise 對象,當函數執行的時候,一旦遇到 await 就會先返回,等到觸發的異步操做完成,再接着執行函數體內後面的語句。
按照mdn解釋 await會暫停當前async 函數執行,而且await 後面是一個表達式,即這個await 等待的是一個表達式(這個表達式返回promise 對象或者一個具體的值):
1 async function testAwait() { 2 const data = await "hello await"; 3 console.log(data) 4 return data 5 }
輸出 「hello await」
返回promose 對象,成功狀態
1 function say() { 2 return new Promise(function(resolve, reject) { 3 setTimeout(function() { 4 let age = 26 5 resolve(`hello, joel。今年我 ${age} 歲`); 6 }, 1000); 7 }); 8 } 9 10 async function demo() { 11 const v = await say(); // 輸出:hello, joel。今年我 26 歲 等待這個say 的異步,若是成功把回調 resole 函數的參數做爲結果 12 console.log(v); 13 } 14 demo();
返回promise 對象,失敗狀態
1 function say() { 2 return new Promise(function(resolve, reject) { 3 setTimeout(function() { 4 let age = 26 5 reject(`hello, joel,發生了異常。今年我 ${age} 歲`); 6 }, 1000); 7 }); 8 } 9 async function demo() { 10 try { 11 const v = await say(); // 輸出:hello, joel,發生了異常。今年我 26 歲 等待這個say 的異步,若是成功把回調 resole 函數的參數做爲結果 12 console.log(v); 13 } catch (e) { 14 console.log(e) 15 } 16 } 17 demo();
async/await 相比原來的Promise的優點在於處理 then 鏈,沒必要把回調嵌套在then中,只要await 便可,如
1 function sing() { 2 return new Promise(function(resolve, reject) { 3 setTimeout(function() { 4 resolve(`來一首好聽的歌吧~~~`); 5 }, 1000); 6 }); 7 } 8 async function demo() { 9 try { 10 const v = await say(); 11 const s = await sing(); 12 console.log(v); // 輸出:hello, joel。今年我 26 歲 13 console.log(s) // 來一首好聽的歌吧~~~ 14 } catch (e) { 15 console.log(e) 16 } 17 } 18 demo();
若是使用原來的Promise 就是把回調放在then()中。