1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > js的定时器 实现页面展示的异步刷新 多线程同步实现方式 附进度条js代码

js的定时器 实现页面展示的异步刷新 多线程同步实现方式 附进度条js代码

时间:2020-05-01 15:08:49

相关推荐

js的定时器 实现页面展示的异步刷新 多线程同步实现方式 附进度条js代码

先简单介绍下两个场景

结果迅速能出来,采用多线程的同步方式

如果逻辑处理比较快,3-5秒任务就会执行完毕,你也可以采用同步多线程同步的方式,代码如下:

数据校验使用到的线程实例:

if(null!=checkDomain.getValueCompares()){

final List<TableValueCompareDomain> valueCompareDomainList = checkDomain.getValueCompares().getTableValueCompare();

//比较的形式

final String valueCompareModeTotal = checkDomain.getValueCompares().getValueCompareModeTotal();

//线程池

ExecutorService fixedThreadPool = Executors.newFixedThreadPool(6);

for(int i=0;i<valueCompareDomainList.size();i++){

//这里用于保证线程的安全性,例如i改变的同时,但是新建的线程被阻塞了,则新建线程所拥有的i也被改变了

final int index = i;

fixedThreadPool.execute(new Runnable() {

public void run() {

valueCompareDomainList.get(index).check();

}

});

}

fixedThreadPool.shutdown();//关闭线程池

//此处不可以删除或注释,需要线程执行结束后再执行别的内容,即只有线程结束后才会继续向下执行

while (!fixedThreadPool.isTerminated()) {

}

}

new DataCheckHive().doTotalResultValueCompare(jobInfoList, totalFileValueCompare, fileNameList, dateStr);

如果处理几十秒才行,采用异步方式+执行状态标志

按条件进行大量数据的查询,因为数据量大的原因,导致可能40秒结果都还没有出来,所以后台采用多线程实现异步的处理方式,先返回;但是问题是查询完成的时候,怎么可以让查询的结果自动展示到前台页面呢?

采用方案:

给被查询页面增加刷新标志,表里面增加字段status,值只能是0或1,0:不需要刷新,1:需要刷新

status的默认值是0。

页面点击查询按钮:

1进度条展示开始,数据统计并入表开始,在统计完成的时候,将status更新为1,怎么确定数据统计完成呢,所有多线程的future.get调用完毕

2页面增加定时查看status的任务开始,status=0,不需要刷新;status=1,需要刷新页面,将status重置为0,返回需要刷新页面的标志,前端进行页面的刷新,同时删除页面里面的js定时器和进度条。

整体代码

点击查询按钮调用的方法--开始查询,并且开始定时任务

// 全局变量 定时器var t1;/*** ajax异步调用多线程开始数据统计,并且开始定时器任务** @param pageId* @param pageType*/function queryAndSaveResult(pageId,pageType){// 参数准备及整理 // 这里页面增加加载进度条__showLoading();// ajax请求开始数据查询$.ajax({type: "POST",url: "../bireport/queryAndSaveResult.action",contentType : "application/json",timeout:20000,dataType:"html",data: JSON.stringify(json),success: function(resp){// 开启定时器获取status,status=0:不需要刷新;status=1,需要刷新页面,且刷新后将status重置为0,同时删除页面里面的js定时器t1=window.setInterval("refreshPage(pageId,pageType,t1)", 1000);},error:function(resp){$.messager.alert('出错了','系统出错,请联系管理员。','error');}});}

后台的查询代码:统计数据,统计数据完成后,异步更新status为1

/*** 功能描述: 按照查询条件保存日活数据** @param:* @return:* @auther: mazhen* @date: /9/3 下午8:03*/@RequestMapping(value="/queryAndSaveResult.action", method = RequestMethod.POST)public @ResponseBodyObject queryAndSaveResult(@RequestBody ResultCondition timeInterval) throws InterruptedException/* throws Exception*/ {//1、查询参数整理与数据准备//2采用了线程池,异步进行数据查询和保存ArrayList<Future> futures = new ArrayList<>();for(final RhQueryConditionNew dto:rhQueryConditionDtos){times = timeOfCondition.get(dto.getId());// 逐日往后推,判断改日的数据是否已经存在,如果已经存在则不查询while(currentTimems<=endTimems) {// 说明该条件下的该日期没有查询过,则if里面查询从改日到最后一日的数据if (!times.contains(dateFormat1.format(currentTimems))) {isSleep = true;Future<?> submit = fixedThreadPool.submit(new QueryTask(dto, dateFormat1.format(currentTimems), endTimeStr, pageId, pageType, rhService));futures.add(submit);// 上面查询到最后日期的数据所以没有必要再进行循环判断了,直接breakbreak;}currentTimems += oneDay;}}// 新开一个异步线程,设置线程,futures执行完毕设置status为1,表示需要刷新展示new Thread(new PageStatusTask(futures,pageId,olapService)).start();Result ret = new Result();ret.setResult(RequestStatus.SUCCESS.getStatus());return ret;}

后台异步设置status的线程代码:数据统计完成,将status更新为1

public class PageStatusTask implements Runnable{static Logger logger = Logger.getLogger ( PageStatusTask.class ) ;ArrayList<Future> futures ;String pageId ;OlapService service;public PageStatusTask(ArrayList<Future> futures ,String pageId,OlapService service){this.futures =futures;this.pageId = pageId;this.service = service;}@Overridepublic void run() {for(Future future : futures){try {future.get();} catch (Exception e) {logger.error("");}}// 所有线程的future.get执行完毕,说明查询已经完成,可以刷新页面的展示了service.updateOlapStatus(Integer.parseInt(pageId), 1);}}

前端获取status的值并进行对应的操作

/*** 定时查看当前页面是否需要刷新展示,status=0,不需要刷新;status=1,需要刷新页面,且刷新后将status重置为0,同时删除页面里面的js定时器* @param pageId 页面id* @param pageType 页面类型* @param t1*/function refreshPage(pageId,pageType,t1){var startTime = $("#dfm1").val();varendTime= $("#dfm2").val();var json = {pageId:pageId};$.ajax({type: "POST",url: "../bireport/queryAndResetPageStatus.action",contentType : "application/json",timeout:2000000,dataType:"html",data: JSON.stringify(json),success: function(resp){// status=0,不需要刷新;status=1,需要刷新页面,且刷新后将status重置为0,同时删除页面里面的js定时器if("1"==resp){openRhShowPage(startTime,endTime,pageId,pageType);__hideLoading();window.clearInterval(t1);}else{console.log("still querying---");}},error:function(resp){$.messager.alert('出错了','系统出错,请联系管理员。','error');}});}

前端定时任代码逻辑如下:先获取status,status=0,不需要刷新;status=1,需要刷新页面,且刷新后将status重置为0,同时删除页面里面的js定时器

使用js定时器的注意点

方法带引号不不带引号的区别:带引号会一直执行,但是如果不带引号则仅仅执行一次

如;

window.setInterval("refreshPage(pageId,pageType,t1)", 1000);//一直执行

window.setInterval(refreshPage(pageId,pageType,t1), 1000);//执行一次

定时的方法中的参数,一定需要是全局变量,如果参数时局部变量,就会出现第一次方法能正常执行,但是第二次及以后参数就变为undefined了。如上面refreshPage(pageId,pageType,t1)中的pageId和pageType。

进度条显示和隐藏的代码如下

function __showLoading(){var sload = $('#loadingdiv');if(sload.size() == 0){sload = $('<div id="loadingdiv" class="sk-spinner sk-spinner-three-bounce" style="position:absolute;z-index:9999"><div class="sk-bounce1"></div><div class="sk-bounce2"></div><div class="sk-bounce3"></div></div>').appendTo('body');window.loadCompCnt = 1;}else{window.loadCompCnt = window.loadCompCnt + 1;}var doc = $(document);var win = $(window);var t = doc.scrollTop() + win.height()/2 - 50;var l = doc.scrollLeft() + win.width()/2 - 50;sload.css({'top':t, 'left':l});sload.show();}function __hideLoading(){window.loadCompCnt = window.loadCompCnt - 1;if(window.loadCompCnt == 0){$("#loadingdiv").remove();delete window.loadCompCnt;}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。