創立自己的 Promise

Abby 旦旦
6 min readSep 11, 2021

--

來創立自己的Promise吧!

基本概念
只是介紹Promise的概念,一般不會這樣寫

使用new的方式讓Promise實體化
const a = new Promise((resolve, reject) => {});
console.log(a);
※ 參數 resolve = 成功的話就會執行
※ 參數 reject = 失敗的話就會執行
※ 一次只會執行一個參數。

可以把上面複製到console看看會得到的結果,可以看到Promise的狀態是<pending>

const a = new Promise((resolve, reject) => {
resolve('success'); → 當成功的話就會執行
// reject('fail'); → 當失敗的話就會執行
});
console.log(a);
a.then((res)=> { → resolve的話使用then
console.log(res)
}).catch((res) => { → reject的話使用catch
console.log(res)
})

可以再把上面複製到console看看會得到的結果,可以看到Promise的狀態是<fulfilled>,並且帶入resolve的值。

一般寫法

function promiseFn(num) {
return new Promise((resolve, reject) => {
setTimeout(() => { // ※使用setTimeout來模擬非同步情形
if (num) { ※如果 num = 真值
resolve('成功');
} else { ※如果 num ≠ 真值
reject('失敗')
}
}, 0);
})
}
// 狀況一
promiseFn(1) // ※num = 1 = 真值
.then(res => { // ※成功的話就執行then
console.log(res);
})
.catch(res => { // ※失敗的話就執行catch
console.log(res);
})

執行以下程式碼,可以看看console.log執行順序

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

promiseFn(1)
.then(res => {
console.log(res);
})
.catch(res => {
console.log(res);
})
console.log('程式碼結束');

會得到 1 → 2 → '程式碼結束' → '成功'。

原因是因為Promise 裡面的setTimeout是非同步,所以會放到最後執行。

鏈接技巧 Promise Chain

function promiseFn(num) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (num) {
resolve('成功');
} else {
reject('失敗')
}
}, 0);
})
}
promiseFn(1)
.then(res => {
console.log(res, 1);
return promiseFn(2);
})
.then(res => {
console.log(res, 2)
return promiseFn(3);
})
.then(res => {
console.log(res, 3)
})
.catch(res => {
console.log(res, 1)
})

會得到 成功1 → 成功2 → 成功3

※ 但要注意,如果鏈接之間其中一個 Pormise 出錯的話,會直接跳到 catch,且錯誤以下的 then 都不會執行。

promiseFn(1)
.then(res => {
console.log(res, 1);
return promiseFn(0);
})
.then(res => {
console.log(res, 2)
return promiseFn(3);
})
.catch(res => {
console.log(res, 1)
})

會得到 成功1 → 失敗1

catch後面可不可以再繼續接then?可以喔!

promiseFn(1)
.then(res => {
console.log(res, 1);
return promiseFn(2);
})
.then(res => {
console.log(res, 2)
return promiseFn(3);
})
.catch(res => {
console.log(res, 1)
return promiseFn(4);
})
.then(res => {
console.log(res, 3)
})

一樣會得到 成功1 → 成功2 → 成功3

如果只想使用 then 來接收成功或失敗的結果,不使用catch:

promiseFn(1)
.then((res)=> {
console.log('success', res)
}, (rej)=> {
console.log('fail', rej)
})

使用 then 帶入兩個 callback function,裡面的參數分別是成功 res 與失敗 rej (可以自己定義名稱),之後再分別寫入想要的值。

進階一點的寫法:

promiseFn(1) //※num = 1 = 真值 = 執行 成功res
.then((res)=> {
console.log('success', res) //※得到這個值
return promiseFn(3) //※回傳這個到下一個then
}, (rej)=> {
console.log('fail', rej)
return promiseFn(3)
})
.then((res)=> { //※num = 3 = 真值 = 執行 成功res
console.log('success', res) //※得到這個值
}, (rej)=> {
console.log('fail', rej)
})

以上範例,會得到兩個 success 成功 的值。

如果一開始的參數是 promiseFn(0),那就會變成:

promiseFn(0) //※num = 0 = 假值 = 執行 失敗rej
.then((res)=> {
console.log('success', res)
return promiseFn(3)
}, (rej)=> {
console.log('fail', rej) //※得到這個值
return promiseFn(3) //※回傳這個到下一個then
})
.then((res)=> { //※num = 3 = 真值 = 執行 成功res
console.log('success', res) //※得到這個值
}, (rej)=> {
console.log('fail', rej)
})

以上範例,會得到 fail 失敗 和 success 成功 的值。

--

--

Abby 旦旦

從零開始轉職網頁設計,正在緩慢朝前端工程邁進中!偶爾會發一些讀後感和UI分享,ㄚㄚ!