一個簡單的例子搞懂ES6之Promise
阿新 • • 發佈:2018-05-06
準備工作 實現 查看 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