關於 JavaScript Promises


Posted by hoyi-23 on 2021-07-06

什麼是 Promise ?

Promise 簡單來說就跟字面上一樣,去promise一件事情,得到兩個回應:

  1. resolve 你完成承諾
  2. reject 你無法完成承諾

範例:
我 Promise 要給你100元

  1. 如果我做到 - Resolve - Success
  2. 如果我沒做到 - 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。

常見非同步執行的問題

  1. CallBack Hell 回呼地獄
    一個非同步行為執行完後,要繼續執行的非同步函式會放在後面,等等等等等,這樣會造成過巢與回呼地獄。
    Promise 是利用串接的語法 .then ,將上一個return的東西傳到下一個執行,避免一直巢狀下去。
  2. 寫法不一致
  3. 無法同時執行 - 非同步行為在執行時,無法確保式何時開始、何時結束的。
    而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


#Promises







Related Posts

 SCSS - @extend vs @include

SCSS - @extend vs @include

[MTR04] W2 D2 位元運算和 JS 基礎:變數

[MTR04] W2 D2 位元運算和 JS 基礎:變數

[第九週] MySQL 語法基礎

[第九週] MySQL 語法基礎


Comments