- Notes
- Run
- Other References
- 利用鏈式呼叫的寫法,簡化層層 callback 的寫法,避免巢狀 Callback Hell
成功callback
和失敗callback
可以被分別定義,增加維護性- 利用維護狀態的方式,控制 callback 的呼叫,只會執行一次
resolve
或reject
callback,降低因撰寫失誤而重複呼叫 callback 的機率
Promise {<pending>}
- __proto__: Promise
- [[PromiseStatus]]: "pending"
- [[PromiseValue]]: undefined
Promise {<resolved>: "Hey, it worked!"}
- __proto__:Promise
- [[PromiseStatus]]:"resolved"
- [[PromiseValue]]:"Hey, it worked!"
狀態是 Promise 的精髓
Status | 轉變時機 | 說明 |
---|---|---|
pending | new Promise() | the promise hasn't fulfilled or reject yet |
fulfilled | call resolve() | the action relating to the promise succeeded |
rejected | call reject() | the action relating to the promise failed |
fulfilled
和rejected
又稱settled
類型的狀態 (the promise has been fulfilled or reject)
純 Promise 基本規則範例,未使用 async, 傳遞參數等情境。
- Promise Executor 會立刻執行
- 所以用 Promise 時通常會包在一個函數中,需要時才呼叫此封裝函數 (參考 Example 3)
- Promise 的狀態一旦變成 settled 類型(
fulfilled
或rejected
),就不能再變動- 因此只有第一個
resolve()
orreject()
有效 - 不能 switch a rejected promise to a fulfilled one
- 因此只有第一個
resolve()
orreject()
only accept zero or one argument (but accept object)- 只有一個
PromiseValue
- 多塞兩個以上的參數不會發生錯誤,但沒有作用
- 只有一個
rejected
被視為發生例外,必須有人處理,否則會發生UnhandledPromiseRejectionWarning
- 定義 reject callback 或 catch()
(node:31062) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 2): Oh no~ not work!
(node:31062) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
$ node src/ex1-promise-basic.js
asynchronous 情境簡易用法,無參數傳遞。
$ node src/ex2-promise-async.js
- 傳遞參數情境的用法
- 封裝 Promise 的寫法,避免立即觸動 Promise Executor,等呼叫時才會正式觸動
$ node src/ex3-promise-encap-n-param.js
- 無論是
resolved
或rejectd
,同一個 Promise 再呼叫一次then()
也會再次觸發對應的 callback function (e.g.pms1
) then()
會回傳一個新的 pending Promise 物件- 該 Promise 的狀態控制由
then()
的 resolved/rejectd callback 的內容控制 (而不是看是執行的是 resolve 或 reject callbacl) - callback 如果
throw
,就算reject()
(e.g.pms4
) - callback 如果
return
另一個 Promise 物件,則以該 Promise 的狀態為準 (e.g.pms6
) - callback 如果沒有
return
(e.g.pms2
,pms3
)或return
一般值(e.g.pms5
),就算resolve()
- 該 Promise 的狀態控制由
$ node src/ex4-promise-then.js
同一個 asynchronous 範例的 callback 版和 Promise 版寫法比較 (極簡範例,只有一層 asynchronous,Promise 優勢不明顯)
$ node src/ex5-ver-callback.js
$ node src/ex5-ver-promise.js
鏈式呼叫的寫法
$ node src/ex6-promise-chaining.js
- 鏈式操作 +
catch()
的寫法 catch()
有兩個作用:- 作為統一的
reject
callback (Case 1) - 充當 try/catch 功能 (Case 3)
- 作為統一的
- 補充:
- 如果同時有自定義的 reject callback 和 catch callback,會以自定義 reject callback 為準 (Case 2)
- 在 resolve 或 reject callback 內出現錯誤,其實會被包裝成一個 rejected promise 拋出來,被下一層的 reject callback 處理 (Case 4), 或 catch 處理(Case 5),但不會被同一層的 reject callback 處理(Case 5)
- 如果都沒有人處理 rejected Promise,會拋錯
UnhandledPromiseRejectionWarning
(Case 6)
$ node src/ex7-promise-catch.js
[Case 1] Ans 1: 11
[Case 2] Ans 1: 11
[Case 3] Ans 1: 11
[Case 4] Ans 1: 11
[Case 5] Ans 1: 11
[Case 6] Ans 1: 11
[Case 4] Error 2: ReferenceError: NotDefinedVar is not defined
[Case 5] Ans 2: 20
[Case 3] Caught! ReferenceError: NotDefinedVar is not defined
[Case 5] Caught! ReferenceError: NotDefinedVar is not defined
[Case 2] Error 2: Arguments must be numbers.
[Case 1] Caught! Arguments must be numbers.
(node:28285) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 3): ReferenceError: NotDefinedVar is not defined
(node:28285) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.