React-Native之定时器Timer的实现代码


Posted in Javascript onOctober 04, 2017

在web开发中,我们通常需要使用定时器功能,使用setTimeout和setInterval函数。

那么在ReactNative中,是否也提供了定时器的功能呢? 答案是肯定的。

我们还是先看看官网怎么说的。

定时器是一个应用中非常重要的部分。React Native实现了和浏览器一致的定时器Timer。

提供的方法如下:

  • setTimeout, clearTimeout
  • setInterval, clearInterval
  • setImmediate, clearImmediate
  • requestAnimationFrame, cancelAnimationFrame

setTimeout (fn, 1000)  和 setInterval (fn,1000)

和web中的意思一样,前者表示延迟1000毫秒后执行 fn 方法 ,后者表示每隔1000毫秒执行 fn 方法。

requestAnimationFrame(fn)和setTimeout(fn, 0)不同,前者会在每帧刷新之后执行一次,而后者则会尽可能快的执行(在iPhone5S上有可能每秒1000次以上)。

setImmediate则会在当前JavaScript执行块结束的时候执行,就在将要发送批量响应数据到原生之前。注意如果你在setImmediate的回调函数中又执行了setImmediate,它会紧接着立刻执行,而不会在调用之前等待原生代码。

Promise的实现就使用了setImmediate来执行异步调用。

InteractionManager(交互管理器)

原生应用感觉如此流畅的一个重要原因就是在互动和动画的过程中避免繁重的操作。在React Native里,我们目前受到限制,因为我们只有一个JavaScript执行线程。不过你可以用InteractionManager来确保在执行繁重工作之前所有的交互和动画都已经处理完毕。

应用可以通过以下代码来安排一个任务,使其在交互结束之后执行:

InteractionManager.runAfterInteractions(() => { 
  // ...需要长时间同步执行的任务... 
});

我们来把它和之前的几个任务安排方法对比一下:

requestAnimationFrame(): 用来执行在一段时间内控制视图动画的代码

setImmediate/setTimeout/setInterval(): 在稍后执行代码。注意这有可能会延迟当前正在进行的动画。

runAfterInteractions(): 在稍后执行代码,不会延迟当前进行的动画。
触摸处理系统会把一个或多个进行中的触摸操作认定为'交互',并且会将runAfterInteractions()的回调函数延迟执行,直到所有的触摸操作都结束或取消了。

InteractionManager还允许应用注册动画,在动画开始时创建一个交互“句柄”,然后在结束的时候清除它。

var handle = InteractionManager.createInteractionHandle(); 
// 执行动画... (`runAfterInteractions`中的任务现在开始排队等候) 
// 在动画完成之后 
InteractionManager.clearInteractionHandle(handle); 
// 在所有句柄都清除之后,现在开始依序执行队列中的任务

TimerMixin

我们发现很多React Native应用发生致命错误(闪退)是与计时器有关。具体来说,是在某个组件被卸载(unmount)之后,计时器却仍然被激活。为了解决这个问题,我们引入了TimerMixin。如果你在组件中引入TimerMixin,就可以把你原本的setTimeout(fn, 500)改为this.setTimeout(fn, 500)(只需要在前面加上this.),然后当你的组件卸载时,所有的计时器事件也会被正确的清除。

这个库并没有跟着React Native一起发布。你需要在项目文件夹下输入npm i react-timer-mixin --save来单独安装它。

var TimerMixin = require('react-timer-mixin'); 
 
var Component = React.createClass({ 
 mixins: [TimerMixin], 
 componentDidMount: function() { 
  this.setTimeout( 
   () => { console.log('这样我就不会导致内存泄露!'); }, 
   500 
  ); 
 } 
});

我们强烈建议您使用react-timer-mixin提供的this.setTimeout(...)来代替setTimeout(...)。这可以规避许多难以排查的BUG。

译注:Mixin属于ES5语法,对于ES6代码来说,无法直接使用Mixin。

如果你的项目是用ES6代码编写,同时又使用了计时器,那么你只需铭记在unmount组件时清除(clearTimeout/clearInterval)所有用到的定时器。

那么也可以实现和TimerMixin同样的效果。例如:

import React,{ 
 Component 
} from 'react-native'; 
 
 
export default class Hello extends Component { 
 componentDidMount() { 
  this.timer = setTimeout( 
   () => { console.log('把一个定时器的引用挂在this上'); }, 
   500 
  ); 
 } 
 componentWillUnmount() { 
  // 如果存在this.timer,则使用clearTimeout清空。 
  // 如果你使用多个timer,那么用多个变量,或者用个数组来保存引用,然后逐个clear 
  this.timer && clearTimeout(this.timer); 
 } 
};

注意点:

1、定时器功能比较简单,注意在es6中使用时,需铭记在unmount组件时清除(clearTimeout/clearInterval)所有用到的定时器。
2、可以使用定时器实现一些普通功能:如短信倒计时等
3、对于一些需要延迟执行的特殊场景也可以使用Timer,譬如:目前RN提供的fetch是没有提供设置超时时间的,如果客户端请求后端的一个接口,接口超时了(后端服务设置的超时时间为10s),那么RN界面就一直loading,也不能aborded。那么这时候我们就可以巧妙的使用计时器,如果客户端发出的Request,时间大于某个值(5秒),那么我们直接认为请求失败。
4、今天还发现一个使用setTimeout的场景,在列表页加载下一页的时候,如果接口响应很快,就不会出现loading的效果,这个时候为了有loading的效果,设置一个500毫秒的延时,呵呵....

参考:http://reactnative.cn/docs/0.31/timers.html#content

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
从数据结构分析看:用for each...in 比 for...in 要快些
Apr 17 Javascript
js/jquery解析json和数组格式的方法详解
Jan 09 Javascript
清除div下面的所有标签的方法
Feb 17 Javascript
js兼容火狐获取图片宽和高的方法
May 21 Javascript
基于Phantomjs生成PDF的实现方法
Nov 07 Javascript
JavaScript之面向对象_动力节点Java学院整理
Jun 29 Javascript
Node.js使用MySQL连接池的方法实例
Feb 11 Javascript
使用vue的transition完成滑动过渡的示例代码
Jun 25 Javascript
详解Axios 如何取消已发送的请求
Oct 20 Javascript
微信小程序如何实现点击图片放大功能
Jan 21 Javascript
maptalks+three.js+vue webpack实现二维地图上贴三维模型操作
Aug 10 Javascript
如何使用gpu.js改善JavaScript的性能
Dec 01 Javascript
vuejs使用$emit和$on进行组件之间的传值的示例
Oct 04 #Javascript
无限循环轮播图之运动框架(原生JS实现)
Oct 01 #Javascript
原生JS实现图片无缝滚动方法(附带封装的运动框架)
Oct 01 #Javascript
原生js封装运动框架的示例讲解
Oct 01 #Javascript
JS Testing Properties 判断属性是否在对象里的方法
Oct 01 #Javascript
基于原生js运动方式关键点的总结(推荐)
Oct 01 #Javascript
vuejs使用递归组件实现树形目录的方法
Sep 30 #Javascript
You might like
php验证码生成代码
2015/11/11 PHP
Symfony2获取web目录绝对路径、相对路径、网址的方法
2016/11/14 PHP
php计算多个集合的笛卡尔积实例详解
2017/02/16 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
js实现运行代码需要刷新的解决方法
2007/08/18 Javascript
javascript for循环设法提高性能
2010/02/24 Javascript
jQuery 选择器理解
2010/03/16 Javascript
非常有用的40款jQuery 插件推荐(系列二)
2011/12/25 Javascript
基于jquery的多功能软键盘插件
2012/07/25 Javascript
不使用jquery实现js打字效果示例分享
2014/01/19 Javascript
jQuery+ajax实现鼠标单击修改内容的方法
2014/06/27 Javascript
分享一个常用的javascript静态类
2014/12/31 Javascript
javascript限制文本框输入值类型的方法
2015/05/07 Javascript
使用EVAL处理jqchart jquery 折线图返回数据无效的解决办法
2015/11/26 Javascript
js弹性势能动画之抛物线运动实例详解
2017/07/27 Javascript
javascript 面向对象实战思想分享
2017/09/07 Javascript
jQueryMobile之窗体长内容的缺陷与解决方法实例分析
2017/09/20 jQuery
解决vue下载后台传过来的乱码流的问题
2020/12/05 Vue.js
[01:08:33]OG vs VGJ.T 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python使用SQLite和Excel操作进行数据分析
2018/01/20 Python
tensorflow1.0学习之模型的保存与恢复(Saver)
2018/04/23 Python
对python制作自己的数据集实例讲解
2018/12/12 Python
idea2020手动安装python插件的实现方法
2020/07/17 Python
DRF框架API版本管理实现方法解析
2020/08/21 Python
selenium框架中driver.close()和driver.quit()关闭浏览器
2020/12/08 Python
企业演讲稿范文
2013/12/28 职场文书
新领导上任欢迎词
2014/01/13 职场文书
毕业生求职信的经典写法
2014/01/31 职场文书
2014年师德师风学习材料
2014/05/16 职场文书
环境工程专业自荐信范文
2014/06/24 职场文书
统计专业自荐书
2014/07/06 职场文书
公安交警中队队长个人对照检查材料思想汇报
2014/10/05 职场文书
2015年学校教研室主任工作总结
2015/07/20 职场文书
求职信如何撰写?
2019/05/22 职场文书
《家庭教育》读后感3篇
2019/12/18 职场文书
Python实现制作销售数据可视化看板详解
2021/11/27 Python