在管理 setTimeout & setInterval 这两个 APIs 时,笔者通常会在顶级(全局)作用域创建一个叫 timer 的对象,在它下面有两个数组成员 —— {sto, siv},用它们来分别存储需要管理的 setTimeoutID / setIntervalID。如下:

var timer = {

sto: [],

siv: []

};

在使用 setTimeout / setInterval 的时候,这样调用:

// 标记 setTimeoutID

timer.sto.push(

setTimeout(function() {console.log("3s")}, 3000);

);

// 标记 setIntervalID

timer.siv.push(

setInterval(function() {console.log("1s")}, 1000)

);

在页面需要 clearTimeout \ clearInterval 的时候,这样调用:

// 批量清除 setTimeout

timer.sto.forEach(function(sto) {clearTimeout(sto)});

// 批量清除 setInterval

timer.siv.forEach(function(siv) {clearInterval(siv)});

暂停 & 恢复

近段时间,笔者发现很多业务都需要「暂停」和「恢复」setTimeout & setInterval 的功能,而仅靠原生的四个 APIs(setTimeout / setIntervale / clearTimeout / clearInterval)是不够用的。于是,笔者对 timer 进行了扩展,使它具备了「暂停」和「恢复」的功能,如下:

// 暂停所有的 setTimeout & setInterval

timer.pause();

// 恢复所有的 setTimeout & setInterval

timer.resume();

扩展后的 timer对象下面挂载6个基础的 APIs。

  • setTimeout

  • setInterval

  • clearTimeout

  • clearInterval

  • pause

  • resume

使用 timer.set* & timer.clear* 来代替原生的 set* & clear*。笔者把扩展后的 timer 托管在 GitHub 仓库上,有兴趣的同学可以移步:https://github.com/leeenx/timer

CreateJS 的启发

在使用 CreateJS 开发一些项目的过程中,笔者发现通过设置 createjs.Ticker.paused = true / false,可以暂停/恢复 createjs.Tween 上的动画。于是笔者借用 createjs.Tween 模拟了 setTimeout & setInterval 的功能,如下:

// setTimeout

createjs.setTimeout = function(fn, delay) {

createjs.Tween.get().wait(delay).call(fn);

}

//setInterval

createjs.setInterval = function(fn, delay) {

createjs.Tween.get().wait(delay).call(fn).loop = 1;

}

具体的代码笔者托管在:createjs.timer(https://github.com/leeenx/createjs.timer)。

其实就是在 createjs 对象下挂载四个 APIs:

  • setTimeout

  • setInterval

  • clearTimeout

  • clearInterval

使用方法与原生的 setTimeout & setInterval 一样,如下:

let siv = createjs.setInterval(() => console.log("1s"), 1000);

createjs.setTimeout(() => createjs.clearInterval(siv), 5000);

时间轴驱动的 timer

createjs.timer 在 CreateJS 项目的开发给笔者带来了极大的便利,但是它必须依赖 createjs.Tween 模块。于是笔者就在思考能否创建一个跟第三方框架无关并且又可以在第三方框架上使用的 timer。

createjs.Ticker.paused 为什么能暂停 createjs.Tween 上的动画的?

createjs.Tween 中每一个动画都有一条自己的时间轴,这条时间轴是通过 createjs.Ticker 来驱动的;当 createjs.Ticker 被暂停后,createjs.Tween 中的每个动画的时间轴也会失去动力而暂停下来。

createjs.Ticker 的作用是提供一个刷新 canvas 画面帧频,通常是使用 requestAnimationFrame or setInterval 来实现的。如果 timer 内部存在一条时间轴,这条时间轴由第三方驱动,那么 timer 就可以与第三方框架状态同步了。

笔者是这样设计 timer 的结构:

  • queue —— 存放 setTimeout or setInterval 的队列;

  • updateQueue —— 驱动 queue 的内部 API;

  • update —— 外部接口,用于对接第三方 Ticker。

实现的伪代码如下:

/*

@queue 成员的结构如下:

{

fn: fn, // 回调函数

type: "timeout or interval", // 类型

elapsed: 0, // 时间轴进度

delay: delay // 目标时长

}

*/

let queue = new Map();

function updateQueue(delta) {

queue.forEach((item, id) => {

item.elapsed += delta;

if(item.elapsed >= item.delay) {

item.fn();

// 从 queue 中删除 setTimeout 成员,interval 成员继续循环

item.type === "timeout" ? delete(id) : (item.elapsed = 0);

}

});

}

// 对外接口

this.update = function(delta) {

updateQueue(delta);

}

timer 的具体实现可以参考:https://github.com/leeenx/es6-utils#timer

timer 与 CreateJS 一起使用:

// es6 代码

import timer from './modules/timer';

// 统一 ticker

createjs.Ticker.addEventListener("tick", function(e) {

e.paused || timer.update(e.delta);

});

timer 与 PIXI 一起使用:

// es6 代码

import timer from './modules/timer';

// 统一 ticker

app.ticker.add("tick", function() {

timer.update(app.ticker.elapsedMS);

});

附上 PIXI 的线上 DEMO,二维码如下:

管理页面的 setTimeout & setInterval的更多相关文章

  1. [BS-10] 统一设置app所有页面的“返回”按钮样式

    统一设置app所有页面的“返回”按钮样式 如果想统一设置app所有页面的“返回”按钮样式,首先自定义WZNavigationController类继承UINavigationController类,然 ...

  2. 通过Web Api 和 Angular.js 构建单页面的web 程序

    通过Web Api 和 Angular.js 构建单页面的web 程序 在传统的web 应用程序中,浏览器端通过向服务器端发送请求,然后服务器端根据这个请求发送HTML到浏览器,这个响应将会影响整个的 ...

  3. 页面的input唤醒软键盘再收起后,页面会出现软键盘高度的空白背景

    微信浏览器在版本6.7.4及以上会有这个bug:页面的input唤醒软键盘再收起后,页面会出现软键盘高度的空白背景,触摸到滚动条会消失恢复! 解决代码 后台框架嵌入iframe的情景,iframe内部 ...

  4. Vue设置页面的title

    原文地址:http://www.cnblogs.com/JimmyBright/p/7410771.html 前端框架如Vue.React等都是单页面的应用,也就是说整个web站点其实都是一个inde ...

  5. js异步处理工作机制(setTimeout, setInterval)

    经常谈到异步,但是发现自己一直没深入理解setTimeout, setInterval,逛论坛的时候发现了这篇好文章,分享一下. ————————————————————以下为原文—————————— ...

  6. 支付宝小程序开发——如何获取支付宝小程序页面的https链接

    前边介绍过通过配置支付宝Scheme协议alipays://来实现h5到小程序的跳转,其实还可以获取小程序页面的https格式链接,虽然支付宝官方并没有直接提供方案,但是通过小程序后台的“码管理”给页 ...

  7. JS魔法堂:定义页面的Dispose方法——[before]unload事件启示录

    前言  最近实施的同事报障,说用户审批流程后直接关闭浏览器,操作十余次后系统就报用户会话数超过上限,咨询4A同事后得知登陆后需要显式调用登出API才能清理4A端,否则必然会超出会话上限.  即使在页面 ...

  8. JavaScript写在Html页面的<head></head>中

    JavaScript写在Html页面的<head></head>中 ----------------- <html> <head> <style ...

  9. 如何将页面的<br/>在Excel中正确换行

    在页面的<br />导致导出Excel中是会以多行的方式显示,达不到页面在一个单元格中进行换行,为此我们有以下两种方式: 1.CSS样式方式 <br style='mso-data- ...

随机推荐

  1. vista x64 vs2010 win32添加资源 未能完成操作解决办法

    非常痛苦的感觉,不能用vc6,msdn library也不好用,去2k3系统试了下,没有任何问题,无奈想重装系统了,但是太浪费时间,装了虚拟机也是vistax64的,安装之后正常... 卸载重新安装依 ...

  2. @Configuration和@Bean

    @Configuration可理解为用spring的时候xml里面的标签 @Bean可理解为用spring的时候xml里面的标签 Spring Boot不是spring的加强版,所以@Configur ...

  3. 深入理解Java 8 Lambda(类库篇——Streams API,Collectors和并行)

    转载:http://zh.lucida.me/blog/java-8-lambdas-inside-out-library-features/ 关于 深入理解 Java 8 Lambda(语言篇——l ...

  4. JS判断是IOS还是Android以及如何解决h5打包后在ios下内容与状态栏重叠问题

    h5打包后在ios下内容与状态栏重叠问题: 1:知道设备的类型: var u = navigator.userAgent, app = navigator.appVersion; var isAndr ...

  5. 用纯css改变下拉列表select框的默认样式(转)

    用纯css改变下拉列表select框的默认样式 分享到 分类 JS学习   关键字 前端   发布 kris  2015-04-01 注意 转载须保留原文链接,译文链接,作者译者等信息.     在这 ...

  6. 有关c#的学习笔记整理与心得

    [ 塔 · 第 一 条 约 定 ] 整理c#:Array Arraylist List Hashtable Dictionary Stack Queue等 Array 的容量是固定的,而 ArrayL ...

  7. freefcw/hustoj Install Guide

    First of all, this version hustoj is a skin and improved for https://code.google.com/p/hustoj/. So t ...

  8. python学习笔记03:python的核心数据类型

    从根本上讲,Python是一种面向对象的语言.它的类模块支持多态,操作符重载和多重继承等高级概念,并且以Python特有的简洁的语法和类型,OOP十分易于使用.Python的语法简单,容易上手. Py ...

  9. nuget程序包还原失败:未能解析此远程名称

    一个简便的方法就是取消下载缺少的程序包. 步骤如下: 1,工具--NuGet程序包管理器--程序包管理器设置 2,NuGet Package Manager--常规,取消勾选.

  10. python 爬虫每天定时启动爬虫任务

     # coding=utf-8 import datetime import time def doSth(): # 这里是执行爬虫的main程序     print '爬虫要开始运转了....'   ...