JS利用闭包自制的沙漏类
Posted 码出世界
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JS利用闭包自制的沙漏类相关的知识,希望对你有一定的参考价值。
【需求】
某应用有一耗时任务,目的是取出一批员工数据显示在页面上,但由于奇特的网络环境,每次调用都要数秒,客户要求在页面上动态显示耗时。
【坑】
动态显示耗时,多会用spanId,setInterval(funciton,mseconds),clearInterval(handler),startTime等一套五六个全局变量和函数。如果需要动态显示耗时的地方不止一处,那么区别和维护一堆全局变量和函数必是费力不讨好的事。
【解决方案】
必须用JS类实现,把要显示事件的SpanId,启动时间和句柄三个变量,启动、显示、停止三个动作都归纳到类里去。
【后台耗时和取数的模拟实现】
@RestController public class MockRestCtrl extends Pager @RequestMapping(value="/fetchEmps", method=RequestMethod.GET) public Map<String,Object> fetchEmps(int waitSeconds) try Thread.sleep(waitSeconds*1000); catch(Exception ex) // Map<String,Object> retvalMap=new LinkedHashMap<String,Object>(); List<Emp> datas=new ArrayList<Emp>(); datas.add(new Emp(1,"Andy",24)); datas.add(new Emp(3,"Bill",34)); datas.add(new Emp(4,"Cindy",44)); datas.add(new Emp(5,"Douglas",54)); datas.add(new Emp(9,"Eliot",64)); retvalMap.put("datas", datas); return retvalMap;
上面代码使用了SpringBoot的RestController来实现后台,响应函数接受waitSecond参数,然后用Thread.sleep歇数秒,之后再造数据送回。
有了这样的后台,前台送入不同的waitSeconds就能实现有差别的耗时。
【沙漏类的实现】(本文重点)
function Sandglass() var spanId; var handler; var startTime; this.setSpanId=function(id) spanId=id; this.start=function(time) startTime=time; handler=setInterval(this.showElapsed,500); this.showElapsed=function() var now=new Date(); var diff=(now-startTime)/1000; var d=parseInt(diff/86400); var h=parseInt(diff/3600)-24*d; var m=parseInt((diff % 3600) / 60); var s=parseInt(diff % 60); var elapsed=d+"day "+h+"hour "+m+"minute "+s+"second"; document.getElementById(spanId).innerText=" 已耗时:"+elapsed; this.stop=function() clearInterval(handler);
以上代码利用闭包实现了私有成员,这些成员只能被函数中定义的函数使用。下面我们可以看看对于使用者来说这个类该怎么用:
【沙漏的初始化】
var sandglass1=new Sandglass(); sandglass1.setSpanId("span1");
【沙漏的启动】
sandglass1.start(new Date());
【沙漏的停止】
sandglass1.stop();
从以上代码可以看出,使用者能用的方法少而简单,较难出错。Sandglass相对复杂的细节把控在了作者手中。
【实现效果】
【前台HTML代码】
<table> <tr> <td width=50%> <table border="1" class="table"> <caption>Table1<span id="span1"></span></caption> <thead> <tr> <td width="120px">id</td> <td width="120px">Name</td> <td width="120px">Age</td> </tr> </thead> <tbody id="table1"> </tbody> </table> </td> <td width=50%> <table border="1" class="table"> <caption>Table2<span id="span2"></span></caption> <thead> <tr> <td width="120px">id</td> <td width="120px">Name</td> <td width="120px">Age</td> </tr> </thead> <tbody id="table2"> </tbody> </table> </td> </tr> </table>
【前台JS代码】
<script type="text/javascript"> var sandglass1=new Sandglass(); sandglass1.setSpanId("span1"); var sandglass2=new Sandglass(); sandglass2.setSpanId("span2"); fillTable(\'table1\',3,sandglass1); fillTable(\'table2\',5,sandglass2); function fillTable(tableId,waitSeconds,sandglass) sandglass.start(new Date()); $.ajax( url:"/mediacool/fetchEmps", data:waitSeconds:waitSeconds, type:"get", dataType:"json", timeout:50000, error:function(xhr,textStatus,errorThrown)alert(\'ajax error\'), success:function(rsps) sandglass.stop(); showDatasInTable(rsps.datas,tableId); , ); function showDatasInTable(datas,tableId) var table=document.getElementById(tableId); // remove remained rows var trs=table.childNodes; for(var i=trs.length-1;i>=0;i--) table.removeChild(trs[i]); // add new rows for(var i=0,n=datas.length;i<n;i++) var data=datas[i]; var td1=document.createElement("td"); td1.appendChild(document.createTextNode(data.id)); var td2=document.createElement("td"); td2.appendChild(document.createTextNode(data.name)); var td3=document.createElement("td"); td3.appendChild(document.createTextNode(data.age)); var tr=document.createElement("tr"); tr.appendChild(td1); tr.appendChild(td2); tr.appendChild(td3); if(i % 2==0) tr.style.backgroundColor="#f5f2eb"; table.appendChild(tr); function Sandglass() var spanId; var handler; var startTime; this.setSpanId=function(id) spanId=id; this.start=function(time) startTime=time; handler=setInterval(this.showElapsed,500); this.showElapsed=function() var now=new Date(); var diff=(now-startTime)/1000; var d=parseInt(diff/86400); var h=parseInt(diff/3600)-24*d; var m=parseInt((diff % 3600) / 60); var s=parseInt(diff % 60); var elapsed=d+"day "+h+"hour "+m+"minute "+s+"second"; document.getElementById(spanId).innerText=" 已耗时:"+elapsed; this.stop=function() clearInterval(handler); </script>
END
以上是关于JS利用闭包自制的沙漏类的主要内容,如果未能解决你的问题,请参考以下文章