Promise初探

遭遇“惡魔金字塔”

項目需要,封裝了一個省市區(qū)的地址選擇器組件。

可以根據(jù)省份id、城市id和區(qū)id對組件設置默認值。邏輯是這樣的:

  1. 獲取省份列表,選中默認省份;
  2. 第一步成功后,根據(jù)默認省份id獲取城市列表,選中默認城市;
  3. 第二部成功后,根據(jù)默認城市id獲取區(qū)列表,選中默認區(qū)。
 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;
                    }
                    //獲取區(qū)
                    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);
                    };
                    });

                }
            });

        }
    });
 };

出現(xiàn)3層嵌套的回調(diào),這就是傳說中的“惡魔金字塔”。確實是惡魔呀,可讀性巨差,自己看著都有點暈,更別說其他人了。

都說ES6的Promise對象讓“惡魔金字塔”聞風喪膽,忍不住來體驗一下。

Promise登場

MDN上這樣定義Promise:
The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.

廢話不多說,來看看使用了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;
    });
};

需要有序地執(zhí)行異步操作的場景,Promise再適合不過了。相比回調(diào)嵌套,層次更分明,可讀性強。

Promise基本原理學習

無論是在異步操作的執(zhí)行之前或執(zhí)行之后,用Promise對象的then方法注冊回調(diào),回調(diào)都能一致執(zhí)行。

很好奇它是怎么做到的,于是自己嘗試寫了個簡易的Promise, 模擬Promise對異步操作的值的代理:
https://gist.github.com/anonymous/402271e9e9c59958279d0fe096e0a277

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運大...
    HetfieldJoe閱讀 8,771評論 0 29
  • 官方中文版原文鏈接 感謝社區(qū)中各位的大力支持,譯者再次奉上一點點福利:阿里云產(chǎn)品券,享受所有官網(wǎng)優(yōu)惠,并抽取幸運大...
    HetfieldJoe閱讀 11,107評論 26 95
  • 特別說明,為便于查閱,文章轉自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 807評論 0 3
  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 編后吐槽:寫的快花眼,很詳細,耐心看必受益匪淺 JavaScript的執(zhí)行環(huán)境是「單線程」的。所謂單線程,是指JS...
    果汁涼茶丶閱讀 4,759評論 8 27

友情鏈接更多精彩內(nèi)容