來創立自己的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 成功 的值。