Reactjs 使用RxJS或任何其他包异步加载Firebase,然后在整个项目中使用它
我的问题不是如何使它工作,而是如何使它正确。。。我正在试验RxJS,但还不确定针对该特定用例的最佳方法是什么 该方法受Firebase团队发布的回购示例的启发: 我的目标是在react应用程序中使用firebase,将WebPack与RxJS一起延迟加载,我计划最终添加redux observable 目前我正在加载firebase,如下所示:Reactjs 使用RxJS或任何其他包异步加载Firebase,然后在整个项目中使用它,reactjs,firebase,webpack,rxjs,firebase-authentication,Reactjs,Firebase,Webpack,Rxjs,Firebase Authentication,我的问题不是如何使它工作,而是如何使它正确。。。我正在试验RxJS,但还不确定针对该特定用例的最佳方法是什么 该方法受Firebase团队发布的回购示例的启发: 我的目标是在react应用程序中使用firebase,将WebPack与RxJS一起延迟加载,我计划最终添加redux observable 目前我正在加载firebase,如下所示: import { from, forkJoin, AsyncSubject } from 'rxjs' import { tap, map } from
import { from, forkJoin, AsyncSubject } from 'rxjs'
import { tap, map } from 'rxjs/operators'
import { authListener } from '../auth/listener'
const CONFIG = {
...
}
const lazyLoadFireBase = (config) => {
const app$ = from(import('firebase/app'))
const firestore$ = from(import('firebase/firestore'))
const fireAuth$ = from(import('firebase/auth'))
return forkJoin(app$, firestore$, fireAuth$).pipe(
map(([firebase]) => {
const app = firebase.initializeApp(config)
app.firestore().settings({ timestampsInSnapshots: true })
app.firestore().enablePersistence()
return app
})
)
}
const firebaseApp = new AsyncSubject()
lazyLoadFireBase(CONFIG)
.pipe(
tap((app) => {
authListener(app)
})
)
.subscribe((app) => firebaseApp.next(app))
export { firebaseApp }
如果我想用firebase做这样的事情,效果会很好,但感觉不是一个正确的方法。我想知道在整个项目中共享延迟加载的Firebase包的更好方法是什么
import { firebaseApp } from '../../../store/firebase'
const logOut = (ev) => {
ev.preventDefault()
firebaseApp.subscribe((app) => {
app.auth().signOut()
})
}
@ggradnig建议实施的变更:
import { from, forkJoin, ReplaySubject } from 'rxjs'
import { tap, map } from 'rxjs/operators'
import { authListener } from '../auth/listener'
const CONFIG = {
}
const lazyLoadFireBase = (config) => {
const app$ = from(import('firebase/app'))
const firestore$ = from(import('firebase/firestore'))
const fireAuth$ = from(import('firebase/auth'))
return forkJoin(app$, firestore$, fireAuth$).pipe(
map(([firebase]) => {
const app = firebase.initializeApp(config)
app.firestore().settings({ timestampsInSnapshots: true })
app.firestore().enablePersistence()
return app
})
)
}
const firebaseApp = new ReplaySubject(1)
lazyLoadFireBase(CONFIG)
.pipe(
tap((app) => {
authListener(app)
})
)
.subscribe((app) => firebaseApp.next(app))
firebaseApp.asObservable()
export { firebaseApp }
我建议有两个改进。首先,不要将Subject或AsyncSubject公开给只需要订阅它的模块。相反,您可以使用firebaseApp.asObservable来获取仅实现Observable的对象 其次,由于主题签名的暴露,您可以在另一个文件中使用unsubscribe,这是您绝对不应该使用的。取消订阅主题将使其他订阅者无法使用它们。所以,只需删除unsubscribe语句。l
现在,除了这两种风格的改进之外,您的方法可能存在真正的问题。AsyncSubject用于封装单个异步操作。它没有缓存机制,这意味着您不能多次订阅同一主题并接收最新的值。主题总是很热门,所以你必须在它发布之前订阅。要解决这个问题,可以使用ReplaySubject1。它将缓存最新的发射,并将其重播给所有未来的订户。感谢您的反馈,我实施了您的更改,效果很好。