一個能夠提高用戶體驗和交互效果的模塊InteractionMnager(交互管理器)es6
使用InteractionManager可讓一些耗時的任務在交互操做或者動畫完成以後進行執行,這樣使用能夠保證咱們的JavaScript的動畫效果能夠平滑流暢的執行。能夠大大提高用戶體驗。好比:導航的轉場動畫web
對大多數React Native應用來講,業務邏輯是運行在JavaScript線程上的。這是React應用所在的線程,也是發生API調用,以及處理觸摸事件等操做的線程。更新數據到原生支持的視圖是批量進行的,而且在事件循環每進行一次的時候被髮送到原生端,這一步一般會在一幀時間結束以前處理完(若是一切順利的話)。若是JavaScript線程有一幀沒有及時響應,就被認爲發生了一次丟幀。 例如,你在一個複雜應用的根組件上調用了this.setState,從而致使一次開銷很大的子組件樹的重繪,可想而知,這可能會花費200ms也就是整整12幀的丟失。此時,任何由JavaScript控制的動畫都會卡住。只要卡頓超過100ms,用戶就會明顯的感受到。後端
屬性方法瀏覽器
runAfterInteractions(task) 靜態方法,在用戶交互和動畫結束之後執行任務 createInteractionHandle() 靜態方法,建立一個句柄(處理器),通知管理器,某個動畫或者交互開始了 clearInteractionHandle(handler:Handle) 靜態方法,進行清除句柄,通知管理器,某個動畫或者交互結束了。 setDeadline(deadline:number) 靜態方法, 設置延遲時間,該會調用setTimeout方法掛起而且阻塞全部沒有完成的任務,而後在eventLoopRunningTime到設定的延遲時間後,而後執行setImmediate方法進行批量執行任務 Events:CallExpression addListener:CallExpression
在應用開發中咱們能夠以下進行執行任務異步
InteractionManager.runAfterInteractions(() => { //執行耗時的同步任務 });
該模塊和其餘相關的調度方法對比:函數
requestAnimationFrame():執行控制動畫效果的代碼
setImmediate/setTimeout():設置延遲執行任務的時間,該可能會影響到正在執行的動畫
runAfterInteractions():延遲執行任務,該不會影響到正在執行的動畫效果
觸摸系統中的單點或者多點觸控都是交互動做,耗時任務會在這些觸摸交互動做執行完成以後或者取消之後回調runAfterInteractions()方法進行執行。oop
InteractionManager也容許應用在動畫開始的時候經過createInteractionHandle()方法註冊動畫生成一個句柄,在結束的時候清除該句柄。fetch
var handle = InteractionManager.createInteractionHandle(); //執行動畫 (`runAfterInteractions` tasks are queued) //動畫執行結束 InteractionManager.clearInteractionHandle(handle); //動畫清除以後,開始直接runAfterInteractions中的任務
runAfterInteractions任務也能夠接收一個普通的回調函數或者一個帶有gen方法而且返回一個Promise的PromiseTask對象。若是參數是PromiseTask對象,那麼任務是異步執行的,也會阻塞。該會等着當前任務執行完畢之後才能執行下一個任務。動畫
默認狀況下,隊列任務會一次性在setImmediate方法中批量執行。若是你經過setDeadline方法設置一個時間值,那麼任務會在延遲該設定值時間進行執行。這時候會調用setTimeout方法進行掛起任務而且阻塞其餘任務的執行。這樣能夠給觸摸交互等操做留出時間更好的相應用戶操做this
具體使用
InteractionManager.runAfterInteractions(() => { //執行耗時的同步任務 navigate("Redeem", { title: "積分兌換" }); })
或者
constructor(props) { super(props); this.state = { renderPlaceholderOnly: true } } render(){ if (this.state.renderPlaceholderOnly) { // Toast.loading("加載中...", 1); return self._renderPlaceholderView(); } return( ..... ) } componentDidMount = () => { InteractionManager.runAfterInteractions(() => { this.setState({ renderPlaceholderOnly: false }); }); };
定時器是一個應用中很是重要的部分。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來執行異步調用。
注意點:
一、定時器功能比較簡單,注意在es6中使用時,需銘記在unmount組件時清除(clearTimeout/clearInterval)全部用到的定時器。
二、可使用定時器實現一些普通功能:如短信倒計時等
三、對於一些須要延遲執行的特殊場景也可使用Timer,譬如:目前RN提供的fetch是沒有提供設置超時時間的,若是客戶端請求後端的一個接口,接口超時了(後端服務設置的超時時間爲10s),那麼RN界面就一直loading,也不能aborded。那麼這時候咱們就能夠巧妙的使用計時器,若是客戶端發出的Request,時間大於某個值(5秒),那麼咱們直接認爲請求失敗。
四、今天還發現一個使用setTimeout的場景,在列表頁加載下一頁的時候,若是接口響應很快,就不會出現loading的效果,這個時候爲了有loading的效果,設置一個500毫秒的延時