JavaScript 核心觀念(75) - Promise - 創立自己的 Promise

前言

我們已經認識了 Promise 基本概念也有稍微撰寫過一些 Promise,但本質上還是要再寫一次,試著建立出屬於自己的 Promise,這樣子記憶力會更猶新。

創立自己的 Promise

前面章節基本上已經有嘗試撰寫過怎麼建立 Promise,所以這邊也在從頭描述一次 Promise 的建立方式。

Promise 要建立時是必須使用 new 關鍵字的,因為本身 Promise 是一個建構函式,通常建構函式會有一個特性,你是無法展開來看的,大多會顯示一個 [native code]

建構函式

如果是普通函式的話,你是可以看到內容的,例如:

普通函式

當然你還是可以透過另一種方式去觀看 Promise 的,例如使用 console.dir 去查看 Promise

Promise

除此之外這邊你可以透過 Promise.prototype 查看了解到我們常常在使用的 thencatch 以及 finally 都在 Promise 原型底下

Promise 原型

接下來講講 Promise 的建立方法,基本上 Promise 在建立的時候必須傳入一個 Callback function,通常寫法有以下

1
2
3
4
5
6
7
8
9
const ps = () => new Promise(() => {
...
});

function ps() {
return new Promise(() => {
...
})
};

而在建立 Promise 時同時也會傳入兩個參數,也就是 resolvereject

1
2
3
4
5
6
7
8
9
const ps = () => new Promise((resolve, reject) => {
resolve('true');
});

function ps() {
return new Promise((resolve, reject) => {
resolve('true');
})
};

接下來在使用上我們就會搭配 thencatch 接收 resolvereject 的結果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const psA = () => new Promise((resolve, reject) => {
resolve('true');
});

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

function psB() {
return new Promise((resolve, reject) => {
resolve('true');
})
};

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

那麼你有發現嗎?其實這邊與前面所撰寫的範例程式碼就非常像了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const promise = (random) => new Promise((resolve, reject) => {
if(random) {
resolve(random);
} else {
reject(random)
}
});

promise(Math.floor(Math.random()*2))
.then((resolve) => {
console.log('resolve', resolve);
}).catch((reject) => {
console.log('reject', reject);
})

只是這邊有一個很重要的觀念要注意一下,也就是 Promise 主要是針對非同步行為做處理,因此 JavaScript 並不會等待 Promise 結果,而是會先往下執行,什麼意思呢?你可以試著貼以下程式碼,你會發現 console.log('A') 是會被優先執行的

1
2
3
4
5
6
7
8
9
10
11
const psA = () => new Promise((resolve, reject) => {
resolve('true');
});

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

console.log('A')

非同步行為

因此如果你希望 Promise 行為執行完畢後才跑其他函式的話,請記得放在 then 裡面。

而這時候或許你會想說,所以 Promise 沒有執行嗎?答案是有執行的,只是非同步的事件被放進事件佇列中等待被觸發(resolvereject),其實 Promise 還是一個 callback function 概念

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
const promise = (random) => {
console.log('Promise', 1)
return new Promise((resolve, reject) => {
console.log('Promise', 2)
setTimeout(() => {
if(random) {
resolve(random);
} else {
reject(random)
}
}, 1000)
})
}

console.log('Window', 1)
promise(Math.floor(Math.random()*2))
.then((resolve) => {
console.log('resolve', resolve);
}).catch((reject) => {
console.log('reject', reject);
})
console.log('Window', 4)

Promise

因此事件佇列的觀念是非常重要的唷。

參考文獻

Liker 讚賞

這篇文章如果對你有幫助,你可以花 30 秒登入 LikeCoin 並點擊下方拍手按鈕(最多五下)免費支持與牡蠣鼓勵我。
或者你也可以考慮請我喝一杯咖啡

Google AD

撰寫一篇文章其實真的很花時間,如果你願意「關閉 Adblock (廣告阻擋器)」來支持我的話,我會非常感謝你 ヽ(・∀・)ノ