---
# System prepended metadata

title: Promise / Async / Await
tags: [ES6, Javascript]

---

# Promise / Async / Await
###### tags: `Javascript` `ES6`
[參考資料](https://wcc723.github.io/development/2020/02/16/all-new-promise/)

JS為了處理非同步事件，時常使用callback function的寫法。
但因此程式碼往往不甚美觀(波動拳 a.k.a callback地獄)
![](https://i.imgur.com/4Iuqxhz.png)
    ->Promise 則是為解決此問題而生。

----
> 複習: js中的非同步事件

JavaScript 屬於同步的程式語言，因此一次僅能做一件事情。
當遇到非同步的事件時，就會將非同步的事件移動到程式碼的最後方，
等到所有的原始碼運行完以後才會執行非同步的事件。
```
console.log('開始');
setTimeout(() => {
console.log('非同步事件');
}, 0);

console.log('程式碼結束'); //開始 -> 程式碼結束 -> 非同步事件
```
---
> Promise
* Promise建構函式上的屬性方法(不必new)(詳見參考資料)
```
Promise.all //透過陣列的形式傳入多個 promise函式，在全部執行完成後回傳陣列結果
Promise.race  //透過陣列的形式傳入多個 promise函式，在全部執行完成後回傳單一結果
Promise.resolve //產生 Promise 物件，必定呈現 resolved 的結果。
Promise.reject //同上。必呈現 rejected 的結果。
```
* Promise 建構函式建立同時，必須傳入一個函式作為參數（executor function）
```
new Promise(function(resolve, reject) { 
    resolve(); // 正確完成的回傳方法
    reject();  // 失敗的回傳方法
});
```
*  Promise 的原型方法

1. ` .then(onFulfilled, onRejected)  // Promise 回傳正確`

onFulfilled：執行成功的callback，所帶入參數表示 Promise 函式中 resolve 所帶入的值。
onRejected：執行失敗的callback，帶入參數表示 Promise 函式中 reject 所帶入的值。

2. `.catch();   // Promise 回傳失敗`
3. `.finally(); // 非同步執行完畢（無論是否正確完成`
catch (前遇reject會直接略過中間的then跳至此)
![](https://i.imgur.com/87D2nwT.png)
then (如要確保全部的then皆被執行，使用then(onRejected))
![](https://i.imgur.com/c8F3NYz.png)


* PromiseState
1. pending：事件已經運行中，尚未取得結果
2. resolved：事件已經執行完畢且成功操作，回傳 resolve 的結果
            （該承諾已經被實現 fulfilled）
3. rejected：事件已經執行完畢但操作失敗，回傳 rejected 的結果

	判斷 Promise 是否完成:
	可依據 Promise 事件中的 resolve() / reject() 是否有被調用。
	若未調用，Promise 的結果則會停留在 pending。
![](https://i.imgur.com/9vhuh4r.png)

* PromiseResult
    
  保存resolve, reject


* return 
	Promise 任務結束後在進行下一個任務時，
	就可以使用 return 的方式進入下一個 then
	1. 方法不限於 promise 函式，任何表達式（expression）都可進行回傳
	2. 如果是 promise 函式，則會繼續遵循 then 及 catch 的運作
	3. 如果不是 promise 函式，在下一個 then 則可以取得結果
-----------
> Async / Await
當 async 被呼叫時他會回傳一個 Promise
如果正確的運行這個 Promise 會回傳一個 resolved
如果函式無法正確地完成，則會拋出錯誤的 rejected。
```
const asyncRun = async () => {
  let mingRun = await runPromise('小明', 2000);
  let auntieRun = await runPromise('漂亮阿姨', 2500);
  return `${mingRun}, ${auntieRun}`
}
asyncRun().then(string => {
  console.log(string)
}).catch(response => {
  console.log(string)
})
```


