iT邦幫忙

0

Javascript 進階 11-3 創立自己的 Promise

  • 分享至 

  • xImage
  •  

這篇文章要來教你如何建立自己的 Promise

首先我們先來看看 Promise 的建構函式~

console.log(Promise);

https://ithelp.ithome.com.tw/upload/images/20200526/201217702hlJa523Ju.png

檢查了以後發現甚麼都看不到,這個時候就要用 console.dir 針對 Promise 進行檢查

console.dir(Promise);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770RRJ1tKZVqf.png

之後你可以看到,如果將 Promise 實體化(new Promise),他可以用的方法就是紅色框框框起來的這些。

那麼 Promise 本身作為物件,被插入的方法就是藍色框框的這些方法:例如上一篇文章介紹到的 Promise.all();

那我們一樣試著將 Promise 實體化 看看。

const a = new Promise();

console.log(a);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770Z55czOc1yM.png

挖~為什麼會跳錯呢?

其實是因為在將 Promise 實體化的時候,同時必須傳入一個 callback 的 function 才行。

const a = new Promise(() => {
            
});

console.log(a);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770HapCetvLwa.png

之後你就會發現,原來這個 Promise 是 pending 的狀態,很正常,因為我們還沒有設定,怎樣的狀況是 resolve ,怎樣的狀況是 reject 。

所以首先我們得先傳入 resolve 以及 reject 的參數,並且同時只能回傳其中一種狀態。

const a = new Promise((resolve, reject) => {
    resolve('成功');
});

console.log(a);

https://ithelp.ithome.com.tw/upload/images/20200526/20121770Iunsas8uMw.png

有沒有看到,當如果我們直接執行 resolve 的語法的話,Promise 的狀態就從 pending 改為 resolved。

那麼如果我們要取得 resolve 所傳入的參數,就要使用 then 的語法去承接

const a = new Promise((resolve, reject) => {
    resolve('成功');
});

console.log(a);
a
    .then((res) => {
        console.log(res);
    });

https://ithelp.ithome.com.tw/upload/images/20200526/20121770h5CbWVigOX.png

那麼今天如果是失敗的 reject 的話呢?

const a = new Promise((resolve, reject) => {
    reject('失敗');
});

console.log(a);
a
    .then((res) => {
        console.log(res);
    });

https://ithelp.ithome.com.tw/upload/images/20200526/20121770F2adRet5bF.png

因為我們沒有使用 .catch 去承接失敗,所以這邊他就提示 Uncaught 的狀態。

const a = new Promise((resolve, reject) => {
    reject('失敗');
});

a
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

https://ithelp.ithome.com.tw/upload/images/20200526/20121770i658P0LQUu.png

這樣就完美接到失敗的訊息嚕!

另外其中的 res 以及 err 都是自訂的參數名稱,你要取甚麼名字都無所謂喔!

以上就是實際上 Promise 的實際操作概念,但是實務上我們不太會這樣使用。

原因在於,a 說到底也只是個物件而已,如果我們有其他的參數要進行判斷、計算、調整,只用物件是沒有辦法的,必需使用一個函式,回傳這個 Promise 的物件,這樣就可以同時傳入參數進行處理,又可以進行 Promise 的定義

那麼關於這個函式,不論你是要使用函式陳述式還是函式表達式都是可以的喔!

範例這邊就先使用函式陳述式來進行開始

// 定義
function promiseFn (num) {
    return new Promise( (resolve, reject) => {
        setTimeout(() => {
            if (num) {
                resolve('成功');
            } else {
                reject('失敗');
            }
        }, 10);
    });
}

// 執行
promiseFn(1)
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

console.log('Code End');

這邊使用的範例就是上一篇文章的範例,現在這樣看起來是不是就懂了呢?

利用 num 的參數判斷是真值還是假值,進而執行 resolve 還是 reject~

執行的時候再用 then 以及 catch 分別接收成功以及失敗的結果。

只是最後不同的地方在於,我這邊多加了一個 Code End,大家想看看,這樣執行的順序是甚麼呢,是結果會先出來,還是 Code End 會先出來呢?

https://ithelp.ithome.com.tw/upload/images/20200526/20121770bEbnf9S7a5.png

答案也是先 Code End 出來,很明顯因為 setTimeout 就是非同步,所以今天就算執行延遲毫秒改成0,也還是一樣。

那麼執行順序會是怎麼樣呢?

// 定義
function promiseFn (num) {
    console.log(1);
    return new Promise( (resolve, reject) => {
        console.log(2);
        setTimeout(() => {
            if (num) {
                resolve('成功');
            } else {
                reject('失敗');
            }
        }, 10);
    });
}

// 執行
promiseFn(1)
    .then((res) => {
        console.log(res);
    })
    .catch((err) => {
        console.log(err);
    });

console.log('Code End');

這邊加上了 1 跟 2 ,也就是說在執行完 2 之後,就先把 setTimeout 放到事件佇列中,在繼續執行 Code End,之後才來執行 setTimeout 的內容。

那麼以上就是基本的 Promise 介紹,透過下一篇文章的內容,可以讓你創建自己的 Promise 的時候更為方便喔!

如果沒有問題的話就可以繼續往下一篇文章邁進嚕~汪汪


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言