iT邦幫忙

2019 iT 邦幫忙鐵人賽

DAY 29
0
Modern Web

JavaScript Note系列 第 29

Promise catch

延續上一個章節,今天來討論Promise的拒絕(rejected)處理。

Promise提供了一個函式,catch( )方法,專門用來處理拒絕(rejected)狀態的Promise。

p.catch(onRejected);
p.catch(function (reason) {
    // rejection
});

它只需要傳入一個參數,處理onRejected的函式,函式參數的reason是錯誤訊息,並回傳一個新的Promise物件。

catch( )方法,相當於呼叫Promise.prototype.then(undefined, onRejected)。

我們先來看一下它的用法,承接上一次的範例:

function async (value) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            if (value)
                resolve(value);
            else
                reject('無輸入值');
        }, Math.floor(Math.random() * 2000));
    })
}
async ('ABC').then(
    response => {
        console.log(`第1次輸入值:${response}`);
        return async ('DEF');
    }).then(
    response => {
        console.log(`第2次輸入值:${response}`);
        return async ('GHI');
    }).catch(
    error => {
        console.log(`錯誤:${error}`);
    }).then(
    response => {
        console.log(`第3次輸入值:${response}`);
    }
);

https://ithelp.ithome.com.tw/upload/images/20181113/20112573NyrCegkdIn.png
在第2個then,回傳'GHI',此時的Promise物件是實現(fulfilled)狀態,所以catch( )不會處理它,而是交由下一個then處理,第3個then接收到值。

如果輸入空字串,Promise物件是拒絕(rejected)狀態,便會執行catch( ),catch( )只會處理相當於then( )的onRejected參數,所以它的下一個then是收不到值的。

response => {
        console.log(`第2次輸入值:${response}`);
        return async ();
    }

https://ithelp.ithome.com.tw/upload/images/20181113/20112573yJ2sBP85Fk.png
不管是then( )或catch( ),它們都會回傳一個全新的Promise物件,包括值也是,當接收不到相對應的值,自然會顯示undefined。

同步的執行,會因為錯誤的發生而中斷,但在Promise中,因為方法串接(method chaining)的關係,整個程序還是會繼續執行,不會中斷,所以才會有undefined的情況。

Promise.all( )

Promise.all( )參數中可以傳入包含多個Promise物件的陣列,只有全部的Promise是實現(fulfilled)狀態,才會執行then( )的onFulfilled函式,並以陣列的型別回傳:

Promise.all([
    async ('A'), async ('B'), async ('C'), async ('D')
]).then(
    response => {
        console.log(response);
    }
).catch(
    error => {
        console.log(error);
    }
);

https://ithelp.ithome.com.tw/upload/images/20181113/201125736jnGiHXIGC.png

其中任一Promise為拒絕(rejected)狀態,就會呼叫catch( )。

Promise.all([
    async ('A'), async ('B'), async (''), async ('D')
]).then(
    response => {
        console.log(response);
    }
).catch(
    error => {
        console.log(error);
    }
);

https://ithelp.ithome.com.tw/upload/images/20181113/20112573R05DCEGaSd.png

Promise.race( )

Promise.all( )參數中可以傳入包含多個Promise物件的陣列,只要任一Promise物件為實現(fulfilled)或拒絕(rejected),就會執行相對應的then( )/catch( )。

因為async( )的計時為亂數,所以回傳的結果不一定,A,B,D跟無輸入值都有可能。

Promise.race([
    async ('A'), async ('B'), async (''), async ('D')
]).then(
    response => {
        console.log(response);
    }
).catch(
    error => {
        console.log(error);
    }
);

參考來源:
MDN Promise.prototype.catch( )
MDN Promise.all( )
MDN Promise.race( )
從Promise開始的JavaScript異步生活


上一篇
Promise
下一篇
window.setTimeout
系列文
JavaScript Note31

尚未有邦友留言

立即登入留言