項目須要,封裝了一個省市區的地址選擇器組件。javascript
能夠根據省份id、城市id和區id對組件設置默認值。邏輯是這樣的:java
getDefaultOptions = () = >{ let { province: provinceId, city: cityId } = this.props.defaultValue; //獲取省份 this.props.dispatch({ type: 'basic/getProvinceList', params: {}, successCallBack: (rs) = >{ let provinceList = rs.provinces; //獲取城市 let params = { province_id: +provinceId }; this.props.dispatch({ type: 'storage/getCityList', params, successCallBack: (rs2) = >{ let cityList = rs2.cities; if (cityList == null) { cityList = []; } if ( + cityId == 0) { this._getOptions(provinceList, [], []); return; } //獲取區 let params = { city_id: +cityId, }; this.props.dispatch({ type: 'storage/getDistrictList', params, successCallBack: (rs3) = >{ let districtList = rs3.districts; if (districtList == null) { districtList = []; } this._getOptions(provinceList, cityList, districtList); }; }); } }); } }); };
出現3層嵌套的回調,這就是傳說中的「惡魔金字塔」。確實是惡魔呀,可讀性巨差,本身看着都有點暈,更別說其餘人了。git
都說ES6的Promise對象讓「惡魔金字塔」聞風喪膽,忍不住來體驗一下。github
MDN上這樣定義Promise:The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.
promise
廢話很少說,來看看使用了Promise後的代碼是怎樣的:異步
sendRequest = (type, params) = >{ return new Promise((resolve, reject) = >{ this.props.dispatch({ type, params, successCallBack: (rs) = >{ resolve(rs); } }); }); }; getDefaultOptions = () = >{ let { province: provinceId, city: cityId } = this.props.defaultValue; let provinceList, cityList, districtList; let _promise = this.sendRequest('basic/getProvinceList', {}); _promise.then(rs = >{ provinceList = rs.provinces ? rs.provinces: []; return this.sendRequest('storage/getCityList', { province_id: +provinceId }) }).then(rs = >{ cityList = rs.cities ? rs.cities: []; //只有省份的狀況 if ( + cityId == 0) { this._getOptions(provinceList, cityList, []); return Promise.reject({ notRealPromiseException: true, }); } return this.sendRequest('storage/getDistrictList', { city_id: +cityId }); }).then(rs = >{ districtList = rs.districts ? rs.districts: []; return this._getOptions(provinceList, cityList, districtList); }). catch(ex = >{ if (ex.notRealPromiseException) { return true; } return false; }); };
須要有序地執行異步操做的場景,Promise再適合不過了。相比回調嵌套,層次更分明,可讀性強。async
不管是在異步操做的執行以前或執行以後,用Promise對象的then方法註冊回調,回調都能一致執行。學習
很好奇它是怎麼作到的,因而本身嘗試寫了個簡易的Promise, 模擬Promise對異步操做的值的代理:
https://gist.github.com/anony...this