首页 > 技术文章 > 异步方法(promise版)出错自调用

sorrowx 2017-08-01 13:50 原文

         /**
         * [*promisePlus promise封装的异步,既然是异步,必然会成功或者失败,理论上失败了就失败了,但是    
         * 失败后能否让他过多长时间自动再调用自己呢,如果调用指定的次数还是失败,那就返回一个数组,数组
         * 里面存的是每次接口失败的信息,如果能够一次成功那就更好。]
         * @param {[type]} promise       [promise版的函数或者promise实例]
         * @param {[type]} count         [调用promise版的函数的次数]
         * 注意: 此函数需要配合co模块使用
         */
        var promisePlus = function(promise, count) {
            var cxt = this,
                args = Array.prototype.slice.call(arguments, 2);

            return function* () {
                var c = 0, message = [], power = 0;
                if (!isPromise(promise) && typeof promise !== 'function') return;
                if (typeof promise === 'function') promise = promise.apply(cxt, args);
                while (true) {
                    ++ power;
                    let t = Math.pow(2, power);
                    if (c ++ >= count) return Promise.reject(new Error(message));
                    try {
                        return yield promise;
                    } catch(err) {
                        message.push(err);
                        console.log('错误次数: ', c, ' 下一次等待时间(单位秒): ', t);
                        yield sleep(t * 1000);
                    };
                };
            };

            function sleep(time) {
                return new Promise((resolve)=>{
                    setTimeout(resolve, time || 1000);
                });
            };

            function isPromise(obj) {
                return 'function' == typeof obj.then;
            };
        };

 

使用姿势:

        // 超时版的fetch
        function _fetch(fetch, timeout) {
            return Promise.race([
                fetch,
                new Promise(function (resolve, reject) {
                    setTimeout(() => reject(new Error('request timeout')), timeout);
                })
            ]);
        };

        function getJSON(url) {
            return new Promise((resolve, reject) => {
                _fetch(fetch(url), 1000*60).then((info)=> {
                    return info.text();
                }).then((info)=> {
                    // console.log('结果');
                    resolve(info);
                }).catch((err)=> {
                    // console.log('出错错错啦');
                    reject(new Error(err));    
                });
            });
        };

        var url = 'http://121.10.140.1233:8080/getRoomDetail?platID=2&roomID=1786565&startDate=2017-06-18&endDate=2017-07-19';
        function getToken() {
            // var url = 'http://121.10.140.123:8080/getRoomDetail?platID=2&roomID=1786565&startDate=2017-06-18&endDate=2017-07-19';
            // var url = 'http://121.10.140.1233:8080/getRoomDetail?platID=2&roomID=1786565&startDate=2017-06-18&endDate=2017-07-19';
            return getJSON(url);
        };


        function sureAdsList() {
            // var url = 'http://121.10.140.123:8080/getXiaoHuLuIndex?startDate=2017-07-11&endDate=2017-07-19&urlID=1786565&platID=2';
            var url = 'http://121.10.140.123:8080/getXiaoHuLuIndex?startDate=2017-07-11&endDate=2017-07-19&urlID=1786565&platID=2';
            return getJSON(url);
        };

        setTimeout(()=>{
            // url = 'http://121.10.140.123:8080/getRoomDetail?platID=2&roomID=1786565&startDate=2017-06-18&endDate=2017-07-19';
        }, 3000);

        // 以上都是准备环境,使用就是这样的(需要引入co模块)
        co(promisePlus(getToken, 5)).then((ret)=>{
            console.log(ret);
        }).catch((err)=>{
            console.log(err);
        });

 

推荐阅读