如何用原生JS实现并行发送AJAX请求?
程序员文章站
2024-01-05 12:52:10
为什么要并行的发送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" }