什麼是 Promise ?
Promise 簡單來說就跟字面上一樣,去promise一件事情,得到兩個回應:
- resolve 你完成承諾
- reject 你無法完成承諾
範例:
我 Promise 要給你100元
- 如果我做到 - Resolve - Success
- 如果我沒做到 - Reject - Fail
let p = new Promise((resolve,reject) => {
let a = '我有給你100元';
if(a == '我有給你100元'){
resolve('Success')
}else{
reject('Failed')
}
})
//若是成功 resolve 會接著跑.then()內的。 如果我有按照承諾給你100元,就會接著跑then。
//若是不成功 reject 會接著跑 .catch() 內的。
p.then((message) => {
console.log('This is in the then' + message)
}).catch((message) => {
console.log('This is in the catch' + message)
})
//因為今天 a 是我有給你100元,所以是resolve,接著跑then,console.log的結果就是
// This is in the then Success
Promise 的用途
Promise 可以代替一些 CallBack Function,常用在當某的事件需要花很久的時間完成時,像是,載入外部圖片、檔案 等。
CallBack Function 就是一個非同步執行的函式,因為非同步執行會發生一些問題,所以出現了 Promise。
常見非同步執行的問題
- CallBack Hell 回呼地獄
一個非同步行為執行完後,要繼續執行的非同步函式會放在後面,等等等等等,這樣會造成過巢與回呼地獄。
Promise 是利用串接的語法 .then ,將上一個return的東西傳到下一個執行,避免一直巢狀下去。 - 寫法不一致
- 無法同時執行 - 非同步行為在執行時,無法確保式何時開始、何時結束的。
而Promise可以做到同時發出請求,並在全部完成再繼續下面的動作。
建立 Promise
//可以使用函式陳述式
function promiseFn(num){
console.log('1')
return new Promise((resolve,reject) => {
//當非同步作業成功時,呼叫 resolve(...),而失敗時則呼叫 reject(...)。
// 在這個例子中,使用 setTimeout(...) 來模擬非同步程式碼。
// 在實務中,您將可能使用像是 XHR 或者一個 HTML5 API.
setTimeout(()=>{
if(num){
resolve('success')
}else{
reject('fail')
}
}, 0)
})
};
promiseFn(0).then((message) => {console.log(message)}
).catch((message) => {console.log(message)})
promiseFn(1).then((message) => {console.log(message)}
).catch((message) => {console.log(message)})
console.log('end')
//執行順序
// 1 -> end -> promise 內
//也可以使用函式表達式
const promiseFn2 = (num) =>{
return new Promise((resolve,reject)=>{
...
})
}
CodePen Promise 練習
Promise Chain
重點: 上一次return的結果,回傳入下一個then中
function promiseFn(num){
return new Promise((resolve,reject) => {
setTimeout(()=>{
if(num){
resolve('success ${num}')
}else{
reject('fail')
}
}, 0)
})
};
promiseFn(1).then( message => {
console.log(message);
return promiseFn(2);
}).then( message => {
console.log(message);
return promiseFn(3);
})....
// promiseFn(2);會傳入第二個then
CodePen Promise Chain
關於 then
前面都是提說 then 接收成功的結果, catch 是失敗的結果。
但其實 then 可以接收成功,也可以接收失敗。
then 其實可以接收兩個 callBack Function! 第一個就是成功,第二個是失敗。
promiseFn(1).then( message => {
console.log(message);
},message => {
console.log(message);
}
)
CodePen promise 的 then 可以接收兩種結果
Promise.all()
一個可以讓所有東西都接受(處理)完,在一起往下執行 then 結果 的方法 !
Promise.all([ 這個陣列裡面的東西全部跑完 ]).then(才會一起到then這裡)
重點: 若是失敗就會直接進入到catch,並且不會繼續執行下去。
Promise.race()
它一樣可以同時傳入多個,但和all不同的地方是,它只會呈現第一個出現的結果。(比賽誰最快xd)
CodePen Promise .all / Promise.race