javascript实现在倒计时线程注册多个事件的功能
javascript实现倒计时的功能,相信很多朋友都做过,直接用setInterval不就行了。但是如果一个应用内有很多地方需要使用倒计时的功能,那不封装一下真的就不行了,至少一个应用内只要一个倒计时的线程在跑就OK了。
公司最近搞的一个项目,就大量使用了倒计时功能。比如有一个抢购功能,可以先预约,到点后系统就会给出通知,然后就能抢购商品。页面上要实现倒计时的显示,按钮的切换。demo地址:http://www.01happy.com/demo/javascript-countdown/
代码可以在demo里通过查看源码看到,这里说明下javascript代码
1.事件类
//事件类 var EventObject = { createNew: function() { var eventObject = {}; /** * 事件执行时间 */ eventObject.excuteTime = 0; /** * 事件执行方法 * @param {int} timestamp * @returns */ eventObject.excute = function(timestamp) { }; return eventObject; } };
我们把要执行的任务理解成一个一个的事件,比如到点切换按钮为立即抢购也可以当成一个事件。每个事件都可以设定执行的事件和执行的方法体。
2.倒计时类
/** * 倒计时类 */ var TimeThreading = { createNew: function() { var timeThreading = {}; /** * setInterval返回ID */ timeThreading.t = {}; /** * 注册要执行的事件 */ timeThreading.eventObjects = new Array(); /** * 开始执行 * @returns {undefined} */ timeThreading.start = function() { var self = this; this.t = setInterval(function() { //获取当期时间戳 var timestamp = Math.ceil((new Date().getTime()) / 1000); var eventObjects = self.getEventObjects(); for (var i in eventObjects) { if (!eventObjects[i].excuteTime) {//如果没有设定执行时间,则直接执行事件 setTimeout(eventObjects[i].excute(timestamp), 1000); } else {//有设定执行时间,则校验当前时间和事件执行时间是否匹配 if (eventObjects[i].excuteTime === timestamp) { setTimeout(eventObjects[i].excute(timestamp), 1000); //事件执行后,则移除该事件。这里并没有考虑事件执行成功与否 self.removeEvent(i); } } } }, 1000); }; /** * 结束执行 */ timeThreading.end = function() { clearInterval(this.t); }; /** * 注册事件 * @param {type} eventObject * @returns {TimeThreading} */ timeThreading.registerEvent = function(eventObject) { this.eventObjects.push(eventObject); return this; }; /** * 移除事件 * @param {type} eventObject * @returns {TimeThreading} */ timeThreading.removeEvent = function(index) { this.getEventObjects().splice(index, 1); return this; }; /** * 获取所有注册的事件 * @returns {Array} */ timeThreading.getEventObjects = function() { return this.eventObjects; }; return timeThreading; } };
单独跑的一个线程,通过start、end方法控制倒计时的运行和停止;通过registerEvent来注册要执行的事件;代码中注释比较详细了,不多做说明,值得一提的是执行每个事件的时候除了直接调用事件的excute的方法,更在外围加了setTimeout。
3. 运行示例
//当前时间戳 var timestamp = Math.ceil((new Date().getTime()) / 1000); //实例化倒计时线程 var timeThreading = TimeThreading.createNew(); //注册时间戳显示事件 var eventObject = EventObject.createNew(); eventObject.excute = function(timestamp) { document.getElementById('show-timestamp').innerHTML = timestamp; }; timeThreading.registerEvent(eventObject); //注册按钮切换到即将开始事件 var willBeginEvent = EventObject.createNew(); willBeginEvent.excuteTime = timestamp + 5; willBeginEvent.excute = function() { document.getElementById('status-btn').innerHTML = "即将开始"; }; timeThreading.registerEvent(willBeginEvent); //注册按钮切换到立即抢购事件 var snapUpEvent = EventObject.createNew(); var timestamp = Math.ceil((new Date().getTime()) / 1000); snapUpEvent.excuteTime = timestamp + 10; snapUpEvent.excute = function() { document.getElementById('status-btn').innerHTML = "立即抢购"; }; timeThreading.registerEvent(snapUpEvent); //注册按钮切换到已经结束事件 var endEvent = EventObject.createNew(); endEvent.excuteTime = timestamp + 15; endEvent.excute = function() { document.getElementById('status-btn').innerHTML = "已经结束"; }; timeThreading.registerEvent(endEvent); //开始倒计时 timeThreading.start();
小结
自己对javascript研究的并不深透,只是用javascript实现了这样的一个思路:一个应用内只跑一个倒计时线程,而后把要执行的事件注册到该线程上,从而实现较好的代码分离效果。
原文链接: http://www.01happy.com/javascript-events-registered-in-the-countdown-thread-function/
相关推荐
JavaScript是单线程语言,但是它可以通过设置超时值和间歇时间值来指定代码在特定的时刻执行。超时值是指在指定时间之后执行代码,间歇时间值是指每隔指定的时间就执行一次代码。 超时调用 超时调用使用window...
JavaScript常用于实现如下功能: |--控制文档的外观和内容; |--对浏览器的控制; |--与 HTML 表单的交互; |--与用户的交互; |--执行计算等。 1.单击事件:定义在按钮的开始标签中 语法:onclick="js语句...
其次,我需要一个任务管理器,该任务管理器可以使用一个计时器实例以不同的时间间隔处理多个任务。 特征 精度和精确度:使用precision选项(默认情况下启用); 由于任务/ CPU负载或时钟漂移,关闭每个滴答之间的...
4.完全多线程 框架允许通过多个线程并发取样和 通过单独的线程组对不同的功能同时取样。 5.精心的GUI设计允许快速操作和更精确的计时。 6.缓存和离线分析/回放测试结果。 JMeter的高可扩展性 1.可链接的取样器允许...
由于现代大多数内核都是多线程的,因此它们可以处理在后台执行的多个操作。 当其中一个操作完成时,内核会告诉Node.js,以便可以将相应的回调添加到 轮询队列 中以最终执行。 我们将在本主题后面进一步详细解释。 ...
ADO.NET 2.0 大批量数据操作和多个动态的结果集 ADO.NET 2.0 异步处理 在ASP.NET中使用WINDOWS验证方式连接SQL SERVER数据库 改进ADO.Net数据库访问方式 ASP.NET 2.0 绑定高级技巧 简单实用的DataSet更新数据库的类+...
前言 相信大家在一开始用angular做项目的时候,一定碰到过...每当有耗费时间较多的任务出现,例如等待一个click事件,等待Ajax请求的回应,我们都会设定一个回调函数,当click事件被触发或者计时器完成,就会创建一个新
但是,如果关键部分内有任何异步代码(可以通过任何I / O操作或计时器简单地触发它),则关键逻辑将跨越多个事件循环,因此并不安全。 考虑以下代码 redis . get ( 'key' , function ( err , value ) { redis . ...
将作业分成块当然是可能的,但是然后将所有数据重新组合在一起并在此期间将其存储在某个地方是一个问题。 大型作业也会消耗大量内存,以致服务器端 JavaScript 运行非常缓慢或根本不运行。 气体线程 是我对这些...
要真正掌握并理解这两个方法,还得从javascript的单线程机制说起。 【开门见山】setTimeout和setInterval是如何工作的呢? 我们知道,js是单线程执行的。所以其实setTimeout和setInterval所谓的“异步调用”事实上是...