Ajax同步请求出现浏览器页面假死,阻塞UI线程之解决方案

来源:互联网 发布:办公软件基础教程 编辑:程序博客网 时间:2024/06/04 18:39

源码:function loadCheckBox(){
var busVedioPosition = '';
var defer = new jQuery.Deferred();
$.ajax({
url:rootPath + "/gis/getBusVedioPosition",
// async:false,
type:"POST",
success:function(result){
defer.resolve(result);
// alert(result.busVedioPosition);
// console.log(result.busVedioPosition);
if(result.success && result.busVedioPosition){
busVedioPosition = result.busVedioPosition;//array
// debugger;
var checkBoxHtml = '';
for(var i=0;i<busVedioPosition.length;i++){

var vehType = document.getElementById("vehTypeCar").value;
var checkBox = document.getElementById("mviewlCheckBox");
if(vehType==0&&busVedioPosition[i].vechType==0){


checkBoxHtml += "<div class=\"checkBoxCss\"><input type=\"checkbox\" onclick=\"checkboxChange(this);\" value="+busVedioPosition[i].passageWayId.substring(5)+">"+busVedioPosition[i].passageWayName+"</div>";
checkBox.innerHTML = checkBoxHtml;
}else if(vehType==1&&busVedioPosition[i].vechType==1){

checkBoxHtml += "<div class=\"checkBoxCss\"><input type=\"checkbox\" onclick=\"checkboxChange(this);\" value="+busVedioPosition[i].passageWayId.substring(5)+">"+busVedioPosition[i].passageWayName+"</div>";
checkBox.innerHTML = checkBoxHtml;


}
}
}
}
});
return defer;
// return defer.promise();


}

问题描述:从库中拿出数据后根据var vehType = document.getElementById("vehTypeCar").value的值向jsp中添加innerHTML类容;
   前提是vehType 有值,而它的值来自于页面中EL表达式接收获取的,所有存在逻辑顺序的问题;

                    如果上面代码中的async为false,也就是同步获取的话,就会执行卡死在js(jQuery)中,搜索一番说是js和页面UI渲染互斥

---引用--- 

(原话:“在发起同步Ajax请求时设置的等待图片在IE与Chrome浏览器不显示,在firefox里面正常,通过Chrome debug模式发现,它是会显示的,由于后面的计算是JQuery同步操作,需要过长时间计算,导致界面UI卡死(来不及展示)。
浏览器的渲染(UI)线程和js线程是互斥的,在执行js耗时操作时,页面渲染会被阻塞掉。当我们执行异步ajax的时候没有问题,但当设置为同步请求 时,其他的动作(ajax函数后面的代码,还有渲染线程)都会停止下来。即使DOM操作语句是在发起请求的前一句,这个同步请求也会“迅速”将UI线 程阻塞,不给它执行的时间。这就是代码失效的原因。jQuery在1.5版本之后,引入了Deferred对象,提供的很方便的广义异步机制。
deferred对象就是jQuery的回调函数解决方案,deferred对象的含义就是"延迟"到未来某个点再执行。
$.ajax()操作完成后,如果使用的是低于1.5.0版本的jQuery,返回的是XHR对象,你没法进行链式操作;如果高于1.5.0版本,返回的是deferred对象,可以进行链式操作。
”出处:http://blog.csdn.net/u012654922/article/details/50113315)

最后:通过对最初代码(下方)

function loadCheckBox(){
var busVedioPosition = '';

//--------------------①
$.ajax({
url:rootPath + "/gis/getBusVedioPosition",
async:false,//--------------------②
type:"POST",
success:function(result){

//--------------------③
if(result.success && result.busVedioPosition){
busVedioPosition = result.busVedioPosition;//array
var checkBoxHtml = '';
for(var i=0;i<busVedioPosition.length;i++){
var vehType = document.getElementById("vehTypeCar").value;
var checkBox = document.getElementById("mviewlCheckBox");
if(vehType==0&&busVedioPosition[i].vechType==0){
checkBoxHtml += "<div class=\"checkBoxCss\"><input type=\"checkbox\" onclick=\"checkboxChange(this);\" value="+busVedioPosition[i].passageWayId.substring(5)+">"+busVedioPosition[i].passageWayName+"</div>";
checkBox.innerHTML = checkBoxHtml;
}else if(vehType==1&&busVedioPosition[i].vechType==1){
checkBoxHtml += "<div class=\"checkBoxCss\"><input type=\"checkbox\" onclick=\"checkboxChange(this);\" value="+busVedioPosition[i].passageWayId.substring(5)+">"+busVedioPosition[i].passageWayName+"</div>";
checkBox.innerHTML = checkBoxHtml;
}
}
}
}
});
//--------------------
}


解决办法:

① 加上      var defer = new jQuery.Deferred();

② 注释掉  async(或者删除)

③ 加上     defer.resolve(result);

④ 加上     return defer;


另附:jQuery API 对Deferred的详解 http://api.jquery.com/?s=Deferred




1 0
原创粉丝点击