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 相关文章推荐
Javascript中正则表达式的全局匹配模式分析
Apr 26 Javascript
基于jquery的button默认enter事件(回车事件)。
May 18 Javascript
JavaScript中为什么null==0为false而null大于=0为true(个人研究)
Sep 16 Javascript
JS获取IP、MAC和主机名的五种方法
Nov 14 Javascript
用js闭包的方法实现多点标注冒泡示例
May 29 Javascript
jQuery中:focus选择器用法实例
Dec 30 Javascript
Javascript中类式继承和原型式继承的实现方法和区别之处
Apr 25 Javascript
Node.js成为Web应用开发最佳选择的原因
Feb 05 Javascript
最后说说Vue2 SSR 的 Cookies 问题
May 25 Javascript
js 实现在2d平面上画8的方法
Oct 10 Javascript
vue + any-touch实现一个iscroll 实现拖拽和滑动动画效果
Apr 08 Javascript
Vue组件系列开发之模态框
Apr 18 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
Joomla开启SEF的方法
2016/05/04 PHP
PHP+Ajax验证码验证用户登录
2016/07/20 PHP
laravel5.1框架model类查询的实现方法
2019/10/08 PHP
javascript 定义初始化数组函数
2009/09/07 Javascript
js DataSet数据源处理代码
2010/03/29 Javascript
jquery div 居中技巧应用介绍
2012/11/24 Javascript
jquery入门必备的基本认识及实例(整理)
2013/06/24 Javascript
jquery submit ie6下失效的原因分析及解决方法
2013/11/15 Javascript
Jquery焦点图实例代码
2014/11/25 Javascript
D3.js中data(), enter() 和 exit()的问题详解
2015/08/17 Javascript
深入理解JavaScript中的call、apply、bind方法的区别
2016/05/30 Javascript
使用JavaScriptCore实现OC和JS交互详解
2017/03/28 Javascript
详解webpack+angular2开发环境搭建
2017/06/28 Javascript
[00:37]DOTA2上海特级锦标赛 Secert 战队宣传片
2016/03/03 DOTA
Python实现二维有序数组查找的方法
2016/04/27 Python
Python中基础的socket编程实战攻略
2016/06/01 Python
常见python正则用法的简单实例
2016/06/21 Python
python如何读写csv数据
2018/03/21 Python
python 动态生成变量名以及动态获取变量的变量名方法
2019/01/20 Python
python基于Selenium的web自动化框架
2019/07/14 Python
在Python中字符串、列表、元组、字典之间的相互转换
2019/11/15 Python
通过Turtle库在Python中绘制一个鼠年福鼠
2020/02/03 Python
用 Python 制作地球仪的方法
2020/04/24 Python
记录模型训练时loss值的变化情况
2020/06/16 Python
html5实现图片转圈的动画效果——让页面动起来
2017/10/16 HTML / CSS
ZWILLING双立人法国网上商店:德国刀具锅具厨具品牌
2019/08/28 全球购物
文秘专业自荐信
2013/10/14 职场文书
高一英语教学反思
2014/01/22 职场文书
幼儿园教师奖惩制度
2014/02/01 职场文书
倡议书范文
2014/04/16 职场文书
参赛口号
2014/06/16 职场文书
2014年党支部工作总结
2014/11/13 职场文书
作弊检讨书范文
2015/05/06 职场文书
2015年小学数学教师个人工作总结
2015/05/25 职场文书
《宝可梦》动画制作25周年到来 官方发布特别纪念视频
2022/04/01 日漫
SQL Server使用CROSS APPLY与OUTER APPLY实现连接查询
2022/05/25 SQL Server