iT邦幫忙

2

JavaScript ES6 - 創建自己的 Promise & 鏈接技巧

這裡來試著創建自己的 Promise 來處理看看非同步 ~

首先用函式建構式創建函式,接著 return 一個 new Promise,並把 resolve(成功) reject(失敗),兩個參數傳入,對應要執行的程式碼,而 num 參數,是要判斷的真假值,如果是真值,就調用 resolve ,反之則調用 reject

function promiseFn(num){
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if(num){
                resolve(`success,${num}`);
            }else{
                reject('fail');
            }
        },10);
    })
}

執行完上面的建立之後,接著就可以來呼叫此函式了
首先先代入 1 這個真值:

promiseFn(1)
.then((res) => {
    console.log(res);
})
.catch((res) => {
    console.log(res);
});
// success,1

跑完之後 console 就會出現預期的 success,就是走成功這條路,使用 then() 這個方法並調用 resolve
如果代入 0 這個假值,就會走失敗這條路,使用 catch() 方法調用 reject

鏈接技巧 Promise chain

在執行非同步的時候,有時候會需要依序執行很多程式碼,這時候就可以使用到鏈接技巧也就是 Promise chain
promise 的建構,以最上面的 function 建構式繼續當例子,然後傳入真假值來決定 resolvereject

全部都是成功(resolve)的情況下鏈接

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

上述先代入了 1 真值,所以走了 then() 這個方法,當要鏈接第二個非同步即可以在 then() 下方 return 要執行的非同步 code,這裡使用同樣的 function,第二次代入了 2 真值,這時候一樣會使用 then() 這個方法,所以在原先的 then() 下方再多了一個 then()
同理,如果都是走成功這條路,只要依序的 return 接著依序的鏈接 then() 即可。

一開始就是失敗(reject)的情況下鏈接

promiseFn(0)
.then((res) => {
    console.log(res);
})
.catch((res) => {
    console.log(res);
    return promiseFn(1)
})
.then((res) => {
    console.log(res);
})
// fail
// success,1

這裡是一開始就代入了 0 假值,直接走了 catch() 這個方法,然而要鏈接的時候,一樣 return 要執行的 code 且在下方補一個 then() 即可。

如果中途有一個失敗(reject)的情況下鏈接

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

這裡會發現執行順序有點特別,如果在途中有一個失敗調用了 catch(),就會發現上面鏈接再多的 then() 都會直接被切斷,僅會執行到 catch() 前一筆的 then()

顛覆你想像的 then,原來還可以這樣用

前面講到了 promise 只有兩條路,要就是成功 resolve 要就是失敗 reject,然後再各別調用 .then().catch()
但這裡要顛覆一下前面講的 ...
要說說 then 其實還可以這樣用,它可以同時塞入兩個 callBack function 意即可以接收成功和失敗兩種結果
所以當不知道非同步會產生哪種結果,而又要使用到鏈接(promise chain)的時候就可以這樣做了:

promiseFn(0)
.then((res)=>{
  console.log(res)
},(res)=>{
  console.log(res)
})

上述第一個 callBack function 是執行成功的結果,第二個 callBack function 是執行失敗的結果,所以當代入 0 這個假值時,就會使用第二個 callBack function,而此時如果要做鏈接,在第一個 callBack function 跟第二個 callBack function 都做 return 就可以了,下方一樣再補一個 then 即可,如下:

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

.then((res)=>{
  console.log(res)
},(res)=>{
  console.log(res)
})
// fail
// success,3

到這裡 then 可以說是矛盾阿~~~ /images/emoticon/emoticon02.gif


尚未有邦友留言

立即登入留言