欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

如何用原生JS实现并行发送AJAX请求?

程序员文章站 2022-03-25 07:57:50
为什么要并行的发送AJAX请求呢?? 如果需要请求很多后台资源,? 那么同事发出所有的请求的效率远高于串形的一个个连续请求.? 并行发出请求所消耗的时延约等于返回最慢的一个请求,...

为什么要并行的发送AJAX请求呢??

如果需要请求很多后台资源,? 那么同事发出所有的请求的效率远高于串形的一个个连续请求.? 并行发出请求所消耗的时延约等于返回最慢的一个请求,? 而串行的时延则是所有请求时延之和.? 如果是jQuery的话可以调用 jQuery.when(deferreds)

以下为我编写的一个JS 并发AJAX请求类.

实现思想是使用一个计数器, 计数器统计处于等待中的AJAX请求数量,? 每个请求发送时计数器++,? 每个数据获取到时计数器 - - , 当计数器重新置为0时说明所有数据均已收到,? 而每个请求返回时将数据填充到对象对应字段中即可.

/**
 * 获取远程数据类(同时发送请求)
 */
function ConcurrencyAjax() {
}
/**
 * 获取数据
 * @param {key:value,,} obj 一个对象里面很多对键值对, key值为数据获取后要填到那个对象中,value值为该数据的后台接口
 * @param {boolean} isAsync 是否异步
 */
ConcurrencyAjax.prototype.LoadRemote = function (obj, isAsync) {
    this.datas = {};
    this.waitAjaxAmount = 0;
    for(var objname in obj) {
        if(typeof obj[objname] != 'string') {
            throw "url is a String, require {key: url}"
        }
        this.waitAjaxAmount++;
        this.loadData(objname, obj[objname], isAsync);
    }
}
/**
 * 获取数据
 * @param {string} obj 一个对象名
 * @param {string} url 一个对象名
 * @param {boolean} isAsync 是否异步
 */
ConcurrencyAjax.prototype.loadData = function (obj, url, isAsync) {
    var me = this;
    var xmlhttp;
    if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari
        xmlhttp = new XMLHttpRequest();
    }
    else {// code for IE6, IE5
        xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
    }
    xmlhttp.onreadystatechange = function () {
        if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
            // console.log(JSON.parse(xmlhttp.responseText));
            me.hasLoadAllSucess(obj, JSON.parse(xmlhttp.responseText));
            
        }
    }
    xmlhttp.open("GET", url, isAsync);
    xmlhttp.send();
}
/**
 * 每单个获取数据后都调用,每次调用函数内不都需要判断是否获取完成所有数据
 * @param {*} objName 一个对象名
 * @param data 获取到的数据
 */
ConcurrencyAjax.prototype.hasLoadAllSucess = function (objName, data) {
    this.datas[objName] = data;
    this.waitAjaxAmount--;
    if(this.waitAjaxAmount == 0) {
        this.getData(this.datas);
    }
}
/**
 * 当所有数据获取完成,调用此函数,此函数需要调用的地方重写覆盖
 * 当重写这个函数的函数被调用时候表示已经获取完成所有数据
 */
ConcurrencyAjax.prototype.getData = function (data) {
    console.log(data);
}

注意:? ?所有数据获取到后调用的函数需要类使用着重载,? 重载后的函数被触发即所有数据已近收到.

LoadRemote函数调用时obj的数据格式

{
     data1: "https://www.data.com/data1",
     data2: "https://www.data.com/data2"
}