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 相关文章推荐
js的event详解。
Sep 06 Javascript
JavaScript 注册事件代码
Jan 27 Javascript
浅谈Javascript Base64 加密解密
Dec 28 Javascript
jquery插件jquery.nicescroll实现图片无滚动条左右拖拽的方法
Aug 10 Javascript
AngularJS仿苹果滑屏删除控件
Jan 18 Javascript
jQuery事件绑定用法详解(附bind和live的区别)
Jan 19 Javascript
HTML5+jQuery插件Quicksand实现超酷的星际争霸2兵种分类展示效果(附demo源码下载)
May 25 Javascript
JS基于HTML5的canvas标签实现炫目的色相球动画效果实例
Aug 24 Javascript
Javascript日期格式化format函数的使用方法
Aug 30 Javascript
30分钟快速入门掌握ES6/ES2015的核心内容(上)
Apr 18 Javascript
详解js模板引擎art template数组渲染的方法
Oct 09 Javascript
Javascript 对象(object)合并操作实例分析
Jul 30 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下使用无限生命期Session的方法
2007/03/16 PHP
php抓取页面的几种方法详解
2013/06/17 PHP
浅析虚拟主机服务器php fsockopen函数被禁用的解决办法
2013/08/07 PHP
PHP输出英文时间日期的安全方法(RFC 1123格式)
2014/06/13 PHP
使用Appcan客户端自动更新PHP版本号(全)
2015/07/31 PHP
php中错误处理操作实例分析
2019/08/23 PHP
laravel执行php artisan migrate报错的解决方法
2019/10/09 PHP
onbeforeunload与onunload事件异同点总结
2013/06/24 Javascript
浅析JavaScript基本类型与引用类型
2014/05/28 Javascript
JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例
2015/02/13 Javascript
jquery 根据name名获取元素的value值
2015/02/27 Javascript
input框中的name和id的区别
2016/11/16 Javascript
使用vue.js实现checkbox的全选和多个的删除功能
2017/02/17 Javascript
基于Vue2x的图片预览插件的示例代码
2018/05/14 Javascript
微信小程序动态增加按钮组件
2018/09/14 Javascript
基于vue2的canvas时钟倒计时组件步骤解析
2018/11/05 Javascript
vue将单页面改造成多页面应用的方法
2018/11/25 Javascript
整理 node-sass 安装失败的原因及解决办法(小结)
2020/02/19 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
2020/04/28 Javascript
[01:32]2014DOTA2西雅图邀请赛 CIS我们有信心进入正赛
2014/07/08 DOTA
使用PYTHON创建XML文档
2012/03/01 Python
Python抓取聚划算商品分析页面获取商品信息并以XML格式保存到本地
2018/02/23 Python
如何安装多版本python python2和python3共存以及pip共存
2018/09/18 Python
Python实现的大数据分析操作系统日志功能示例
2019/02/11 Python
基于树莓派的语音对话机器人
2019/06/17 Python
django 数据库返回queryset实现封装为字典
2020/05/19 Python
Pycharm打开已有项目配置python环境的方法
2020/07/03 Python
Python实现像awk一样分割字符串
2020/09/15 Python
基于Jquery和Css3代码制作可以缩放的搜索框
2015/11/19 HTML / CSS
党建目标管理责任书
2014/07/25 职场文书
世界读书日的活动方案
2014/08/20 职场文书
老人节标语大全
2014/10/08 职场文书
初中教务主任竞聘演讲稿(范文)
2019/08/20 职场文书
中国现代文学之经典散文三篇
2019/09/18 职场文书
python scipy 稀疏矩阵的使用说明
2021/05/26 Python
Python常用配置文件ini、json、yaml读写总结
2021/07/09 Python