『新手日記』Day-25 Promise的初次見面
最近…真的會完蛋,早上MLB晚上CPBL等到了11月還有世界杯…..該不該把電視砸了…
Promise 本身是用來改善 JavaScript 非同步的語法結構。JavaScript 是屬於同步的程式語言,因此『一次僅能做一件事情』,但遇到非同步的事件時,就會將非同步的事件移動到程式碼的最後方,等到所有的原始碼運行完以後才會執行非同步的事件。
1 | console.log('開始'); |
用這個例子就可以很好說明,相信有很多人新手會跟我一樣直覺反應因為setTimeout設定為0所以回直接執行,所以印出來的順序會是:開始 →非同步事件 →程式碼結束。
但結果卻是:
雖然setTimeout 所定義的時間為 0,但因為是屬於非同步事件,因此還是會在其他原始碼運行完以後才執行。
在了解了非同步後,我們來認識一下:Promise
Promise
Promise 是一個物件建構子 (constructor),使用時需要先從 Promise 物件產生物件實例 (instance),再使用繼承特性的 instance 去包裝程式碼的 callback 流程。
Promise 是用於進行流程控制的物件 (容器),它具備了 callback 的優點,但透過 .then()
來標明流程,而 .then()
之間可以互相鏈結 (chaining),把之前「一層包一層的 callback」,轉換成 .then()
的串接。
一個 Promise
物件處於以下幾種狀態:
- 擱置(pending):初始狀態,不是 fulfilled 與 rejected。
- 實現(fulfilled):表示操作成功地完成。
- 拒絕(rejected):表示操作失敗了。
而他可以使用的 methods 有以下:
[Promise.all](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise/all%3E)
[Promise.race](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise/race)
[Promise.reject](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise/reject)
[Promise.resolve](https://developer.mozilla.org/zh-TW/docs/Web/JavaScript/Reference/Global_Objects/Promise/resolve)
一個 Promise
物件透過 new
及其建構式建立。這個建構式接收一個叫作”執行器函式(executor function)“的引數。此函式接收兩個函式作為引數。第一個函式(resolve)
在非同步作業成功完成時,以該作業之結果值被呼叫。第二個函式(reject
)在作業失敗時,以失敗訊息,通常是一個 error object,被呼叫。
1 | const myFirstPromise = new Promise((resolve, reject) => { |
Promise 建構函式 new 出的物件,則可以使用其中的原型方法(在 prototype
內),其中就包含 then
、catch
、finally
,這些方法則必須在新產生的物件下才能呼叫。
透過 new Promise()
的方式建立 p
物件,此時 myFirstPromise 就能使用 Promise 的原型方法:
1 | const myFirstPromise =new Promise();myFirstPromise.then();// Promise 回傳正確 |
上述解釋大部份都是由mdn翻譯而來,我們用另外一個作者所講解的方式相信各位會更了解:
Promise 的意義
Promise,如字面的意思就代表 承諾。
承諾的未來
當你拿到一個 Promise 的時候,代表在未來中這個 Promise 可能會有幾種狀況發生
承諾 被兌現 (fulfilled)
- 用
resolve()
來兌現
承諾 被打破 (rejected)
- 用
reject()
來表示失敗
承諾 一直沒有回應 (pending)
- 一直沒有回傳
也就是說,承諾代表的不見得是成功。
未來之後
而根據這三種結果,我們接下來的動作會有所不同,如果:
承諾被兌現 就 繼續做預定好的下一件事
- 使用
.then()
承諾被打破 就 根據這個原因去做對應的動作
- 使用
.catch()
,或是.then
的第二個參數 - 承諾 一直都沒有回應 就 繼續等下去
是不是很快就搞懂了。
💡 Promise Chain:.then
不論是非同步或者同步的程式都可以串接,而 then
會回傳一個 Promise
。