您好,登錄后才能下訂單哦!
在web開發(fā)中,我們通常需要使用定時器功能,使用setTimeout和setInterval函數(shù)。
那么在ReactNative中,是否也提供了定時器的功能呢? 答案是肯定的。
我們還是先看看官網(wǎng)怎么說的。
定時器是一個應(yīng)用中非常重要的部分。React Native實現(xiàn)了和瀏覽器一致的定時器Timer。
提供的方法如下:
setTimeout (fn, 1000) 和 setInterval (fn,1000)
和web中的意思一樣,前者表示延遲1000毫秒后執(zhí)行 fn 方法 ,后者表示每隔1000毫秒執(zhí)行 fn 方法。
requestAnimationFrame(fn)和setTimeout(fn, 0)不同,前者會在每幀刷新之后執(zhí)行一次,而后者則會盡可能快的執(zhí)行(在iPhone5S上有可能每秒1000次以上)。
setImmediate則會在當前JavaScript執(zhí)行塊結(jié)束的時候執(zhí)行,就在將要發(fā)送批量響應(yīng)數(shù)據(jù)到原生之前。注意如果你在setImmediate的回調(diào)函數(shù)中又執(zhí)行了setImmediate,它會緊接著立刻執(zhí)行,而不會在調(diào)用之前等待原生代碼。
Promise的實現(xiàn)就使用了setImmediate來執(zhí)行異步調(diào)用。
InteractionManager(交互管理器)
原生應(yīng)用感覺如此流暢的一個重要原因就是在互動和動畫的過程中避免繁重的操作。在React Native里,我們目前受到限制,因為我們只有一個JavaScript執(zhí)行線程。不過你可以用InteractionManager來確保在執(zhí)行繁重工作之前所有的交互和動畫都已經(jīng)處理完畢。
應(yīng)用可以通過以下代碼來安排一個任務(wù),使其在交互結(jié)束之后執(zhí)行:
InteractionManager.runAfterInteractions(() => { // ...需要長時間同步執(zhí)行的任務(wù)... });
我們來把它和之前的幾個任務(wù)安排方法對比一下:
requestAnimationFrame(): 用來執(zhí)行在一段時間內(nèi)控制視圖動畫的代碼
setImmediate/setTimeout/setInterval(): 在稍后執(zhí)行代碼。注意這有可能會延遲當前正在進行的動畫。
runAfterInteractions(): 在稍后執(zhí)行代碼,不會延遲當前進行的動畫。
觸摸處理系統(tǒng)會把一個或多個進行中的觸摸操作認定為'交互',并且會將runAfterInteractions()的回調(diào)函數(shù)延遲執(zhí)行,直到所有的觸摸操作都結(jié)束或取消了。
InteractionManager還允許應(yīng)用注冊動畫,在動畫開始時創(chuàng)建一個交互“句柄”,然后在結(jié)束的時候清除它。
var handle = InteractionManager.createInteractionHandle(); // 執(zhí)行動畫... (`runAfterInteractions`中的任務(wù)現(xiàn)在開始排隊等候) // 在動畫完成之后 InteractionManager.clearInteractionHandle(handle); // 在所有句柄都清除之后,現(xiàn)在開始依序執(zhí)行隊列中的任務(wù)
TimerMixin
我們發(fā)現(xiàn)很多React Native應(yīng)用發(fā)生致命錯誤(閃退)是與計時器有關(guān)。具體來說,是在某個組件被卸載(unmount)之后,計時器卻仍然被激活。為了解決這個問題,我們引入了TimerMixin。如果你在組件中引入TimerMixin,就可以把你原本的setTimeout(fn, 500)改為this.setTimeout(fn, 500)(只需要在前面加上this.),然后當你的組件卸載時,所有的計時器事件也會被正確的清除。
這個庫并沒有跟著React Native一起發(fā)布。你需要在項目文件夾下輸入npm i react-timer-mixin --save來單獨安裝它。
var TimerMixin = require('react-timer-mixin'); var Component = React.createClass({ mixins: [TimerMixin], componentDidMount: function() { this.setTimeout( () => { console.log('這樣我就不會導(dǎo)致內(nèi)存泄露!'); }, 500 ); } });
我們強烈建議您使用react-timer-mixin提供的this.setTimeout(...)來代替setTimeout(...)。這可以規(guī)避許多難以排查的BUG。
譯注:Mixin屬于ES5語法,對于ES6代碼來說,無法直接使用Mixin。
如果你的項目是用ES6代碼編寫,同時又使用了計時器,那么你只需銘記在unmount組件時清除(clearTimeout/clearInterval)所有用到的定時器。
那么也可以實現(xiàn)和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,那么用多個變量,或者用個數(shù)組來保存引用,然后逐個clear this.timer && clearTimeout(this.timer); } };
注意點:
1、定時器功能比較簡單,注意在es6中使用時,需銘記在unmount組件時清除(clearTimeout/clearInterval)所有用到的定時器。
2、可以使用定時器實現(xiàn)一些普通功能:如短信倒計時等
3、對于一些需要延遲執(zhí)行的特殊場景也可以使用Timer,譬如:目前RN提供的fetch是沒有提供設(shè)置超時時間的,如果客戶端請求后端的一個接口,接口超時了(后端服務(wù)設(shè)置的超時時間為10s),那么RN界面就一直loading,也不能aborded。那么這時候我們就可以巧妙的使用計時器,如果客戶端發(fā)出的Request,時間大于某個值(5秒),那么我們直接認為請求失敗。
4、今天還發(fā)現(xiàn)一個使用setTimeout的場景,在列表頁加載下一頁的時候,如果接口響應(yīng)很快,就不會出現(xiàn)loading的效果,這個時候為了有l(wèi)oading的效果,設(shè)置一個500毫秒的延時,呵呵....
參考:http://reactnative.cn/docs/0.31/timers.html#content
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。
免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。