# Promise / Async / Await
###### tags: `Javascript` `ES6`
[參考資料](https://wcc723.github.io/development/2020/02/16/all-new-promise/)
JS為了處理非同步事件,時常使用callback function的寫法。
但因此程式碼往往不甚美觀(波動拳 a.k.a callback地獄)

->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跳至此)

then (如要確保全部的then皆被執行,使用then(onRejected))

* PromiseState
1. pending:事件已經運行中,尚未取得結果
2. resolved:事件已經執行完畢且成功操作,回傳 resolve 的結果
(該承諾已經被實現 fulfilled)
3. rejected:事件已經執行完畢但操作失敗,回傳 rejected 的結果
判斷 Promise 是否完成:
可依據 Promise 事件中的 resolve() / reject() 是否有被調用。
若未調用,Promise 的結果則會停留在 pending。

* 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)
})
```