在web開發中,我們通常需要使用計時器功能,使用setTimeout和setInterval函數。本文主要介紹了React-Native之定時器Timer的實作程式碼,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟著小編過來看看吧,希望能幫助大家。
那麼在ReactNative中,是否也提供了定時器的功能呢? 答案是肯定的。
我們還是先看看官網怎麼說的。
計時器是一個應用程式中非常重要的部分。 React Native實作了和瀏覽器一致的定時器Timer。
提供的方法如下:
setTimeout, clearTimeout
setInterval, clearInterval
#setImmediate, clearImmediate
requestAnimationFrame, cancelAnimationFrame
setTimeout (fn, 1000) 與setInterval (fn,1000)#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毫秒的延時,呵呵....
相關推薦:
#以上是React-Native定時器Timer如何實現的詳細內容。更多資訊請關注PHP中文網其他相關文章!