js/javascript 异步执行方法
有两个方法A和B,方法B比较耗时,方法A是向DOM里面append500个tr,方法B是向DOM里面追加5000个tr,以至于方法B执行的时候浏览器会卡住几秒不能动,请问...
有两个方法A和B,方法B比较耗时,方法A是向DOM里面append 500个tr,方法B是向DOM里面追加5000个tr,以至于方法B执行的时候浏览器会卡住几秒不能动,请问有什么方法能让方法B在后台执行或者不卡住浏览器的吗?
展开
2016-01-08 · 做真实的自己 用良心做教育
千锋教育
千锋教育专注HTML5大前端、JavaEE、Python、人工智能、UI&UE、云计算、全栈软件测试、大数据、物联网+嵌入式、Unity游戏开发、网络安全、互联网营销、Go语言等培训教育。
向TA提问
关注
展开全部
var xmlHttp;
function createXMLHttpRequest(){
//Mozilla 浏览器(将XMLHttpRequest对象作为本地浏览器对象来创建)
if(window.XMLHttpRequest){ //Mozilla 浏览器
xmlHttp = new XMLHttpRequest();
}else if(window.ActiveXObject) { //IE浏览器
//IE浏览器(将XMLHttpRequest对象作为ActiveX对象来创建)
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){}
}
}
if(xmlHttp == null){
alert("不能创建XMLHttpRequest对象");
return false;
}
}
//用于发出异步请求的方法
function sendAsynchronRequest(url,parameter,callback){
createXMLHttpRequest();
if(parameter == null){
//设置一个事件处理器,当XMLHttp状态发生变化,就会出发该事件处理器,由他调用
//callback指定的javascript函数
xmlHttp.onreadystatechange = callback;
//设置对拂去其调用的参数(提交的方式,请求的的url,请求的类型(异步请求))
xmlHttp.open("GET",url,true);//true表示发出一个异步的请求。
xmlHttp.send(null);
}else{
xmlHttp.onreadystatechange = callback;
xmlHttp.open("POST",url,true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlHttp.send(parameter);
}
}
//以上代码是通用的方法,接下来是调用以上的方法
function loadPros(title,count,pid,cid,level){
// 调用异步请求方法
url = "。。。。。。。。";
sendAsynchronRequest(url,null,loadCallBack);
}
// 指定回调方法
function loadCallBack(){
try
{
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
if(xmlHttp.responseText != null && xmlHttp.responseText != ""){
var divProid = document.getElementById('videolist');
divProid.innerHTML = xmlHttp.responseText;
for(i=0;i<len;i++)
{
var video_url = document.getElementById("videolist"+i+"").href;
if(video_url != undefined && video_url != null && video_url != ""){
window.location.href = video_url;
}
}
}
}
}
if (xmlHttp.readyState == 1)
{
//alert("正在加载连接对象......");
}
if (xmlHttp.readyState == 2)
{
//alert("连接对象加载完毕。");
}
if (xmlHttp.readyState == 3)
{
//alert("数据获取中......");
}
}
catch (e)
{
//alert(e);
}
}
function createXMLHttpRequest(){
//Mozilla 浏览器(将XMLHttpRequest对象作为本地浏览器对象来创建)
if(window.XMLHttpRequest){ //Mozilla 浏览器
xmlHttp = new XMLHttpRequest();
}else if(window.ActiveXObject) { //IE浏览器
//IE浏览器(将XMLHttpRequest对象作为ActiveX对象来创建)
try{
xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
}catch(e){
try {
xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
}catch(e){}
}
}
if(xmlHttp == null){
alert("不能创建XMLHttpRequest对象");
return false;
}
}
//用于发出异步请求的方法
function sendAsynchronRequest(url,parameter,callback){
createXMLHttpRequest();
if(parameter == null){
//设置一个事件处理器,当XMLHttp状态发生变化,就会出发该事件处理器,由他调用
//callback指定的javascript函数
xmlHttp.onreadystatechange = callback;
//设置对拂去其调用的参数(提交的方式,请求的的url,请求的类型(异步请求))
xmlHttp.open("GET",url,true);//true表示发出一个异步的请求。
xmlHttp.send(null);
}else{
xmlHttp.onreadystatechange = callback;
xmlHttp.open("POST",url,true);
xmlHttp.setRequestHeader("Content-Type","application/x-www-form-urlencoded;");
xmlHttp.send(parameter);
}
}
//以上代码是通用的方法,接下来是调用以上的方法
function loadPros(title,count,pid,cid,level){
// 调用异步请求方法
url = "。。。。。。。。";
sendAsynchronRequest(url,null,loadCallBack);
}
// 指定回调方法
function loadCallBack(){
try
{
if (xmlHttp.readyState == 4) {
if (xmlHttp.status == 200) {
if(xmlHttp.responseText != null && xmlHttp.responseText != ""){
var divProid = document.getElementById('videolist');
divProid.innerHTML = xmlHttp.responseText;
for(i=0;i<len;i++)
{
var video_url = document.getElementById("videolist"+i+"").href;
if(video_url != undefined && video_url != null && video_url != ""){
window.location.href = video_url;
}
}
}
}
}
if (xmlHttp.readyState == 1)
{
//alert("正在加载连接对象......");
}
if (xmlHttp.readyState == 2)
{
//alert("连接对象加载完毕。");
}
if (xmlHttp.readyState == 3)
{
//alert("数据获取中......");
}
}
catch (e)
{
//alert(e);
}
}
展开全部
var count = 0;
// 这里例子是500次分为一步, 可以实际调整
function add500() {
for (var i = 0; i < 500; i++) {
// do something
}
console.log(count)
if (++count < 10) {
setTimeout(add500);
}
}
add500();
循环次数太多就可以采用异步分阶段执行
追问
如果方法还没有执行完的话,这样会导致浏览器卡住吗?因为目前最大的问题就是浏览器会卡住。
追答
/**
* 分段异步执行循环
* @param start 循环的起始值
* @param range 总的循环次数
* @param step 一次异步执行的循环次数, 默认100次
* @param callback 每次循环执行的回调函数
* @return
*
* @usage exeStep(1, 5, 2, function(i){console.log(i)});
*/
function exeStep(start, range, step, callback)
{
var max = start + Math.min(range, step || 100);
for (var i = start; i < max; i++)
{
typeof callback === 'function' && callback(i);
}
if (i < start + range)
{
setTimeout(function()
{
exeStep(i, range - (max - start), step, callback);
});
}
}
本回答被提问者和网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
首先,js是单线程执行的。所以你说的同时执行A,B个人觉得可能无法实现。
基本上来说,对于dom的操作,由于浏览器要重新去计算,所以很耗时,你可以线生成5000个tr,然后,在将这5000个tr追加进去。因为数据量比较大,肯定还是很耗时。但是一定会比你现在一个个的追加方式省时。
事实上,这么大的数据,从设计上来说已经很有问题了。如果是测试没问题,如果在生产中这么使用,只能说是自作孽了。
基本上来说,对于dom的操作,由于浏览器要重新去计算,所以很耗时,你可以线生成5000个tr,然后,在将这5000个tr追加进去。因为数据量比较大,肯定还是很耗时。但是一定会比你现在一个个的追加方式省时。
事实上,这么大的数据,从设计上来说已经很有问题了。如果是测试没问题,如果在生产中这么使用,只能说是自作孽了。
追问
也不是要两个方法一起执行,先执行A接着执行B都可以,现在我就是把剩下的5000个tr拼接起来,一次性追加进去,但是页面就会卡住。用户不能操作,有什么办法不让浏览器卡住吗?只要不卡住问题就好解决了。
追答
如果一个页面显示5000个tr在可是区域是显示不玩的。设置事件延迟加载,首先将5000个tr分为第一屏内容比如说50个tr。一次只加载一屏的内容,然后,当用户鼠标滚动或者是滑动滚动条的时候,再去加载。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
个人建议:
方法1:做一个“数据加载中。。。”的模态窗口,但执行B方法的时候就显示出这个模态窗口,禁止一切操作,方法执行完以后再关闭模态窗口。
方法2:试试把5000个tr保存到一个字符串,然后一次性append进去。
方法3:直接在后台生成,设置成display:none,需要的时候再显示出来。
方法1:做一个“数据加载中。。。”的模态窗口,但执行B方法的时候就显示出这个模态窗口,禁止一切操作,方法执行完以后再关闭模态窗口。
方法2:试试把5000个tr保存到一个字符串,然后一次性append进去。
方法3:直接在后台生成,设置成display:none,需要的时候再显示出来。
追问
唉,就是不想让用户知道我们在加载东西,要让他感觉是一瞬间就加载出来了,所以模态窗口不允许,方法二就是现在用的方法,是拼接好5000个tr的字符串一次性设置的。方法三的话,还是会导致浏览器卡住,加载完成之后才能操作。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
原因:
卡顿的原因不是说A,B生成慢的原因。关键在于dom节点添加后页面的刷新耗时
解决几种方法:
1、A,B同时添加完后,同时刷新
2、A,B节点先从dom树中移除,添加完后再把A,B节点添加到DOM树中,这样只刷新一次。
3、A,B节点隐藏,然后添加A,B节点,添加完后,再显示A,B节点。
卡顿的原因不是说A,B生成慢的原因。关键在于dom节点添加后页面的刷新耗时
解决几种方法:
1、A,B同时添加完后,同时刷新
2、A,B节点先从dom树中移除,添加完后再把A,B节点添加到DOM树中,这样只刷新一次。
3、A,B节点隐藏,然后添加A,B节点,添加完后,再显示A,B节点。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
追加tr的时候不要一次性加5000个,这样肯定会卡呀
可以考虑用setinterval 设置延时,一次加载500个,分10次加载等或者更多次加载
可以考虑用setinterval 设置延时,一次加载500个,分10次加载等或者更多次加载
追问
这个方法还是会卡住浏览器,我都试了一次加载100个,都会卡顿。。。
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询