Skip to content

Instantly share code, notes, and snippets.

@radex
Created November 9, 2018 15:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save radex/9759dc1ea23a25628b80ed06f466264f to your computer and use it in GitHub Desktop.
Save radex/9759dc1ea23a25628b80ed06f466264f to your computer and use it in GitHub Desktop.
1. set up a Prefetcher instance, for example in your router component
2. when you want to display another part of the app, call:
```
prefetcher.prefetch(screenConcretePrefetcher, 'my-screen', () => {
// prefetch done! you can call setState() or whatever to actually start rendering a tree
})
```
// @flow
/* eslint-disable no-console */
import type { Subscription, Observable } from 'rxjs'
import { combineLatest } from 'rxjs/observable/combineLatest'
export type PrefetcherFunction = () => Observable<any>[]
export default class Prefetcher {
_prefetchSubscription: ?Subscription
_prefetchComplete = false
// Fetches data from all observables passed in, then calls onComplete (or if there was an error)
// If prefetch is aborted manually or by another prefetch, onComplete will never be called
prefetch(prefetcher: ?PrefetcherFunction, diagnosticTag: string, onComplete: () => void): void {
// Abort previous prefetch operation
this.abort()
// If no prefetcher, done!
if (!prefetcher) {
onComplete()
return
}
// Prefetch
console.log(`Begin prefetching ${diagnosticTag}`)
console.time && console.time(`prefetch-${diagnosticTag}`)
const prefetchItems = prefetcher()
// $FlowFixMe
const observable = combineLatest(prefetchItems)
this._prefetchSubscription = observable.subscribe(
() => {
if (!this._prefetchComplete) {
console.log(`End prefetching ${diagnosticTag}`)
console.time && console.timeEnd(`prefetch-${diagnosticTag}`)
this._prefetchComplete = true
onComplete()
}
},
() => {
console.warn(`Error prefetching ${diagnosticTag}`)
console.time && console.timeEnd(`prefetch-${diagnosticTag}`)
onComplete()
},
)
}
// Stops whatever prefetch operation may have been in progress (it will never complete)
abort(): void {
this._prefetchSubscription && this._prefetchSubscription.unsubscribe()
this._prefetchComplete = false
}
}
const prefetchProject = (
project: Project
): Observable<any>[] => {
// return an array of all observables components in a subtree will need to render instantly
return [
project.author.observe(), // you can pass on observables from Relations
project.tasks.observe(), // … and from Queries
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment