相信大家在面对一个 没有 requirejs、seajs、webpack等遵循commonjs规范的项目的时候,想要使用jQuery的ajax同时请求不互相依赖的多个文件(例如一些地图数据的json文件:country.json、country-i18n.json、provinces.json、provinces-i18n.json等)或数据(由多个请求拿到的数据组成),当这些请求都完成时才执行函数的时候,一般会这么写:

//例如
$.getJSON('./json/country.json',function(data1){
    $.getJSON('./json/country-i18n.json',function(data2){
        $.getJSON('./json/provinces.json',function(data3){
            $.getJSON('./json/provinces-i18n.json',function(data4){
                //更多嵌套...
                //需要同时拿到data1、data2、data3、data4才能画图
                //因为这几个json(每个体积不一样大或网络影响)无法确定请求完成时间,谁快谁慢,所以需要嵌套请求
            })
        })
    });
});

看起来就很恶心,而且极大的影响了程序执行的速度,如下图:
pic

但是我们希望是这样的,所有请求是同时的,并且当这些请求都完成时执行函数,如下图:
这里写图片描述

代码如下:

//例如
var times = 0,files = ['country','country-i18n','provinces','provinces-i18n'],datas = {};
files.forEach(function(file){
    $.getJSON('./json/' + file + '.json',function(data){
        datas[file] = data;
        trigger();
    });
});

function trigger() {
    times++;
    if (times === files.length) {
        complete()
    }
}
function complete(){
    //do something...
}

最终封装后的代码如下:

;(function($){
    /**
     * $.ajaxs
     * 批量同时发送异步ajax请求。
     * (注意:请求是无序的,若要有序,则可设置globalOpt为true或{byOrder: true},此时是非同时的)。
     *
     * @param {Array} opts - 放置ajax配置的数组;
     * 可以是:[{},{},...] 、[url_1,url_2,...];
     * 每个opt对象的配置就是$.ajax的配置。
     * @param {function} [fn] - 当所有的请求成功时的回调函数。
     * @param {Object|boolean} [globalOpt] - 每个opts配置的共同设置;
     * 类似于$.ajax的配置,多了个byOrder属性;
     * (注意:个别的会覆盖全局的)。
     * @returns {Object} - jQuery对象。
     */
    $.extend({
        ajaxs: function (opts, fn, globalOpt) {
            var times = 0, byOrder = false, datas = [];
            if (typeof globalOpt === 'boolean') {
                byOrder = globalOpt;
                globalOpt = {byOrder: byOrder};
            } else {
                byOrder = globalOpt.byOrder;
            }
            $.each(opts, function (i, opt) {
                opt = typeof opt === 'object' ? opt : {url: opt};
                var _globalOpt = $.extend(true, {}, globalOpt),
                    _success = opt.success || _globalOpt.success || $.noop,
                    _opt = $.extend(_globalOpt, opt, {
                        success: function (data, textStatus, $XHR) {
                            _success(data, textStatus, $XHR, i);
                            datas[i] = data;
                            trigger();
                        }
                    });
                byOrder ? (opts[i] = _opt) : $.ajax(_opt);
            });
            byOrder && $.ajax(opts[times]);

            function trigger() {
                times++;
                if (times === opts.length) {
                    fn && fn(datas);
                } else {
                    byOrder && $.ajax(opts[times]);
                }
            }

            return this;
        }
    });
})(jQuery);

项目地址

码云
github


本文转载:CSDN博客