JavaScript – Promise

前言

JavaScript 的 Promise已經是不可或缺的實用方式,之後的async,await也是只Promise的應用,但我總覺得要依官方說明-Promise來解釋不是很容易懂,一個主要是名詞的定義,另一個是沒有實際的原始碼,所以我試著用我自已的方式去理解並介紹這個重要的功能。

Test Source

const myResolve = (result) => {console.log(`function myResolve has been executed, and result is ${result}`)};
const myReject = (result) => {console.log(`function myReject has been executed, and result is ${result}`)};

/*不呼叫resolve或reject*/
const execution01 = (resolve, reject) => {
    const name = "task01";
    console.log(`I'm ${name}`);
}

/*呼叫resolve*/
const execution02 = (resolve, reject) => {
    const name = "task02";
    console.log(`I'm ${name}`);
    resolve(name);
}

/*呼叫reject*/
const execution03 = (resolve, reject) => {
    const name = "task03";
    console.log(`I'm ${name}`);
    reject(name);
}

/*設定目前測試的execution*/
const execution = execution01;

const px = new Promise(execution);
console.log(px);

const p = new Promise(execution);
console.log(p);
const p2 = p.then(myResolve, myReject);
console.log(p2);

先定義了三個execution,除了執行我主要的工作console.log外,execution02在結束時呼叫resolve,execution03在結束時呼叫reject
再來我定義了myResolve,myReject,這個兩準備用在then裡的function。

一開始比較會有疑問的在於resolve跟reject,因為在這裡看不出這是什麼,實際上這是在Promise執行時,由Promise送進來的function;另一個是execution,在官方文件中,是用executor來稱呼這個要執行的function,但我覺得,這是一個被執行的function,而不是一個主動去執行的executor,所以我比較喜歡叫它execution.

Test001

第一個execution

const execution01 = (resolve, reject) => {
    const name = "task01";
    console.log(`I'm ${name}`);
}

結果

I'm task01
Promise { <state>: "pending" }

I'm task01
Promise { <state>: "pending" }
Promise { <state>: "pending" }

execution中,我只做我想做的事,然後不呼叫resolve或reject,Promise的state是”pending”
如果呼叫then,很明顯,then沒有作用,但還是回傳一個Promise物件。

Test002

第二個execution

const execution02 = (resolve, reject) => {
    const name = "task02";
    console.log(`I'm ${name}`);
    resolve(name);
}

結果

I'm task02
Promise { <state>: "fulfilled", <value>: "task02" }

I'm task02
Promise { <state>: "fulfilled", <value>: "task02" }
Promise { <state>: "pending" }
function myResolve has been executed, and result is task02

execution中,我做完我想做的事,然後呼叫resolve,Promise的state是”fulfilled”
如果有呼叫then,myResolve會被用到

Test003

第三個execution

const execution03 = (resolve, reject) => {
    const name = "task03";
    console.log(`I'm ${name}`);
    reject(name);
}

結果

I'm task03
Promise { <state>: "rejected", <reason>: "task03" }
uncaught exception: "task03"

I'm task03
Promise { <state>: "rejected", <reason>: "task03" }
Promise { <state>: "pending" }
function myReject has been executed, and result is task03

execution中,我做完我想做的事,然後呼叫resolve,Promise的state是”rejected”,而且還外加送我一個exception。
如果有呼叫then,myReject有被用到,而且exception不見了!!

檢視

這樣看起來,Promise裡有一個executor。
在進行new Promise的constructor時,就我給的execution function放到Thread裡執行,還偷塞了兩個function進來,這兩個function除了用來保留處理的結果,還會改變Promise的狀態。
如果我都沒有用到這兩個偷塞的function,Promise的狀態就不會改變。
當我想對Promise呼叫then時,我要送兩個function給它,Promise裡的executor會在我呼叫resolve或reject時,把先前處理的結果再送到這兩個function裡。

所以Promise的狀態不是因為我寫的Exection主體結果而改變,而是依據我呼叫的是resolve或reject。

總結

  1. 在進行new Promise的constructor時,就有人提供Thread來執行execution
  2. resolvereject是Promise提供的,用來保留結果及改變Promise的狀態。
  3. 自行定義的myResolvemyReject,只能在then時使用,Promise會把先前保留的結果送進去。

One thought to “JavaScript – Promise”

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *

這個網站採用 Akismet 服務減少垃圾留言。進一步了解 Akismet 如何處理網站訪客的留言資料