项目须要,封装了一个省市区的地址选择器组件。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