1. 程式人生 > >一個簡單的例子搞懂ES6之Promise

一個簡單的例子搞懂ES6之Promise

準備工作 實現 查看 AS spa div 原理 事件 例子

ES5中實現異步的常見方式不外乎以下幾種:

1. 回調函數

2. 事件驅動

2. 自定義事件(根本上原理同事件驅動相同)

而ES6中的Promise的出現就使得異步變得非常簡單。promise中的異步是這樣的:

* 每當我需要執行一次異步操作的時候,我都需要new一個promise對象

* 每一個異步操作的Promise對象都需要設定一個成功執行的條件和成功的回調、一個失敗的條件和失敗的回調

* Promise對象可通過執行then()方法獲得成功的回調信息

* Promise對象可通過執行catch()方法捕獲失敗的回調信息(當不執行catch方法時,若異步操作失敗會報錯)

一次常規異步操作的流程大致是這樣的:

    new Promise((resolve, reject)=>{
        if(...){             // 設定異步操作成功的條件
            resolve()        // 設定異步操作成功 並返回 成功的回調信息
        } 
        else{               // 設定異步操作失敗的條件
            reject()        // 設定異步操作失敗 並返回 失敗的回調
        }
    })
    .then((res)=>{         //執行異步操作,並且執行成功
..... // 異步操作成功後的後續操作 ... .. }) .catch((err)=>{ // 執行一步操作,異步操作失敗 ..... // 操作失敗的後續操作 ... .. })

下面首先通過一個簡單的例子來基本套用一下異步操作的流程

實際項目中經常會有這樣的需求,很多功能都是需要在登錄後才能去實現的,比如說我想要查看用戶的個人信息,那麽這個用戶就必須先要登錄,那麽分解步驟後

第一步: 執行登錄並且登錄成功

第二步: 登錄成功,開始獲取用戶信息

第三步: 獲取用戶信息成功,返回用戶信息或成功的回調信息。

以上三步操作,需要兩次異步操作,就需要兩個異步的Promise對象

首先是準備工作:

    // 兩個狀態用以分別判斷兩次異步操作是否成功
    let status1 = 1;
    let status2 = 1;
    // 設定登錄的異步操作
    let doLogin = (resolve, reject) =>{
        setTimeout(()=>{
            if(status1 ==1){
                resolve({status:1,msg: `異步執行 login ok`})
            }else{
                reject({status:0,msg: `異步執行 login failed`});
            }
        },2000)
    }
    // 設定獲取用戶信息的異步操作
    let getUserInfo = (resolve, reject)=>{
        setTimeout(()=>{
            if(status2==1){
                resolve({status:1,msg: `異步執行 get user info ok`});
            }else{
                reject({status:0,msg: `異步執行 get user info failed`});
            }
        },1000)
    }

緊接著開始執行異步操作:

    new Promise(doLogin)
    .then((res)=>{
        if(res.status==1){
            console.log(res.msg);
            return new Promise(getUserInfo)     // 若下一步要執行異步操作則必須返回一個promise對象用以鏈式操作
        }else{
            console.log(res.msg);
        }
    })
    .then((res)=>{
        console.log(res.msg)
    })
    .catch((err)=>{
        console.log(err.msg)
    })

感興趣的可以通過控制status1、status2兩個狀態碼體驗一下不同情況下異步操作的流程與結果。

上面的例子搞清楚之後差不多也就理解了promise的基本用法。

你也可以配合同步代碼體驗效果:

    console.log("同步執行111111111")
    new Promise(doLogin)
    .then((res)=>{
        if(res.status==1){
            console.log(res.msg);
            return new Promise(getUserInfo)
        }else{
            console.log(res.msg);
        }
    })
    .then((res)=>{
        console.log(res.msg)
    })
    .catch((err)=>{
        console.log(err.msg)
    })
    console.log("同步執行2222222")

而當你需要實現連續的異步操作時,需要在每一步異步操作後都返回一個promise對象,否則執行的還是同步操作。下面的例子可以證明:

    let afterLogin1 = ()=>{
        console.log("登錄後續操作1")
    }
    let afterLogin2 = ()=>{
        console.log("登錄後續操作2")
    }

    new Promise(doLogin)
    .then((res)=>{
        console.log(res.msg)
    })
    .then((res)=>{
        setTimeout(()=>{
            afterLogin1();
        },1000)
    })
    .then((res)=>{
        afterLogin2();
    })

例子的輸出結果為:

異步執行 login ok

登錄後續操作2

登錄後續操作1

一個簡單的例子搞懂ES6之Promise