react-native中有时候须要定时执行一些后台任务,好比定时发送消息,定时统计数据等.这个时候就须要使用另外注册一个视图来作这些东西了,否则在同步任务中作这些任务,一旦任务比较耗时就会卡住后面的进程,甚至致使后面的进程再也不渲染页面.javascript
在合适的位置:页面启动或者某个须要的时候,注册并启动咱们的另一个视图.这个时候其实至关于启动了另一个线程.java
这里注意一下,这个视图里的东西千万不要直接刷新UI相关的数据,全部的内容都应该是内存相关的.react
AppRegistry.registerRunnable('RunableTask', TaskRun) AppRegistry.runApplication('RunableTask', {});
调用init
方法,启动咱们本身的定时器刷新方法,这里我暂时定义1秒刷新一次,低于1秒间隔的定时器将不在执行.这里也是为了防止部分人设置低间隔的定时器致使APP崩溃.react-native
这里使用react-native内部提供的requestAnimationFrame
方法,每次刷新的时候先判断一次是否能够执行任务.app
const tasks = new Map(); let currDate = Date.now(); /** * 初始化 */ exports.init = function () { global.requestAnimationFrame(run); } /** * 执行,每秒执行一次 * 保证秒级工做正确 */ function run() { const now = Date.now(); if (now > currDate + 1000) { currDate = now; tasks.forEach(item => item.preStart(now)); } global.requestAnimationFrame(run); }
全部的任务都须要继承这个基类,定时器运行的时候也会经过基类内部的方法去判断是否须要执行方法.这里对外实现了一个timer是时间间隔,单位是毫秒,还有一个start方法用来给每一个任务使用的.函数
经过每次执行preStart方法判断下次执行的时间到了没有来决定是否执行自定义方法.若是到了同时还要计算下一次的时间并存好.测试
/** * 基础工做类 */ class Jobs { name = "base"; /** * 下次执行时间戳 */ nextTime = 0; /** * 重载:时间间隔 */ timer = 0; /** * 预启动 */ preStart(now) { if (this.timer < 1000) return; if (this.nextTime > now) return; if (this.nextTime === 0) return this.nextTime = now + this.timer; this.nextTime += this.timer; this.start(now); } /** * 重载:执行一次设置的方法 */ start() { } }
将设置好的任务加入全局的map示例中,运行的时候会从这个示例中取须要的任务出来.this
/** * 添加一个工做 * @param {*} name 名称 * @param {*} time 时间 * @param {*} fn 执行函数 */ const addJob = (name, Job) => tasks.set(name, new Job()) exports.addJob = addJob; /** * 取消任务 * @param {*} name */ const cancelJob = name => tasks.delete(name); exports.cancelJob = cancelJob;
这里模拟一次定时发送统计消息.url
另一个地方实现了将每次须要发送的消息存入内存中,这里只负责取出须要发送的消息.线程
设置3秒执行一次发送任务,若是数量比较少就修改定时任务的间隔,后面的任务延迟发送.
若是后台接收一次大量的数据,也能够将屡次统计合并为一次统计,请求的个数会更少一些.
/** * 定时触发统计方法 */ class TrackJob extends Jobs { timer = 3000; start() { let list = TackList(); if (list.length > 10) { this.timer = 3000; } else { this.timer = 5000; } list.forEach(item => { request.trackData(item.url, item.data); log("埋点事件", item.data); }) } } addJob("Track", TrackJob);
在目前的基础上扩展时间间隔的设定方式,实现固定时间日期执行任务.这里可能须要app一直活着才能保证.
加入执行次数,执行超过必定的此时就再也不执行.