今天遇到这个需求,同一页面可能会向后台同时发起多个相同的ajax请求,发起请求的是页面不同的模块,这些模块出现是随机的独立的,我们无法通过如jq的when加载完成数据,再统一处理。总不能同一个ajax都请求一次后台,太浪费资源。实现原理大概是:同时发起多个请求,封装的函数
http
只接受第一次的请求,并且将每次请求的参数存到数组中,等到请求成功以后,遍历存起来数组中,执行里面的回调函数
// 此处仅用 setTimeout 模拟ajax请求
/**
* 函数作用 同一ajax请求同时发起多个,只请求一次后台
* @param key string 当前请求的唯一key,由请求url+请求参数去除特殊字符后组成
* @param callback function 请求回调函数
* @return no return
*/
function http(key,callback){
var task='task_'+key;//区分不同请求链接
if (typeof window[task]==='undefined') {
window[task]=[];
setTimeout(function(){
window[key]=key+'data';//模拟后台返回数据
// 请求成功后执行数组中的回调函数
for (var k in window[task]) {
var oneTask=window[task][k];
if (typeof oneTask.callback==='function') oneTask.callback(window[oneTask.key]);
}
window[task]=undefined;
},1000);
};
// 每一个请求参数存到数组
window[task].push({
key:key,
callback:callback
});
};
// ===================== 调试
http('url',function(res){
console.log('res',res);
});
http('url2',function(res){
console.log('res',res);
});
http('url2',function(res){
console.log('res',res);
});
setTimeout(function(){
http('url3',function(res){
console.log('res',res);
});
},800);
setTimeout(function(){
http('url5',function(res){
console.log('res',res);
});
},900);
setTimeout(function(){
http('url6',function(res){
console.log('res',res);
});
},1100);
以下是使用jq的ajax封装示例
/**
* 函数作用 同一ajax请求同时发起多个,只请求一次后台
* @param key string 当前请求的唯一key,由请求url+请求参数去除特殊字符后组件
* @param callback function 请求回调函数
* @return no return
*/
function http(options,callback){
// 根据options.url和options.data 生成key
var dataStr=options.data?JSON.stringify(options.data):'';
var key=options.url+dataStr;
var key='u'+encodeURIComponent(key).replace(/%|\.|http|https|www/img,'');
var task='task_'+key;// 区分不同链接的task
if (typeof window[task]==='undefined') {
window[task]=[];
$.ajax(options).done(function(res) {
window[key]=res;
for (var k in window[task]) {
var oneTask=window[task][k];
if (typeof oneTask.callback==='function') oneTask.callback(window[oneTask.key]);
}
window[task]=undefined;//本批处理完成立即销毁,否会影响下一批请求
})
};
// 请求的参数存到数组中,待请求完成再集中触发数组里面回调函数
window[task].push({
key:key,
callback:callback
});
};
////////////////////以下为调用测试,共发起三个ajax,其中两个是相同请求的,在控制台中查看,只发起两个ajax请求
http({
url: '/',
type: 'GET',
dataType: 'json',
data: {"a":1}
},function(res){
console.log('res',res);
})
http({
url: '/',
type: 'GET',
dataType: 'json',
data: {"a":1}
},function(res){
console.log('res',res);
})
http({
url: location.href,
type: 'GET',
dataType: 'json',
data: {"a":1}
},function(res){
console.log('res',res);
})
网友评论