Rx Swift 丢弃 .do(onNext: ) 我如何让它触发?
Posted
技术标签:
【中文标题】Rx Swift 丢弃 .do(onNext: ) 我如何让它触发?【英文标题】:Rx Swift discards .do(onNext: ) How do I make it trigger?Rx Swift 丢弃 .do(onNext: ) 我如何让它触发? 【发布时间】:2020-10-12 11:28:18 【问题描述】:我正在尝试将我的firebase
项目转换为与rx swift
一起使用,但.do(onNext:)
被丢弃,而onCompleted
触发器在subscription
中。
我做了firebase
代码的observable
函数:
func fetchFireBaseData() -> Observable<[Recipe]>
return Observable.create( [weak self] observer -> Disposable in
guard let self = self else return Disposables.create()
self.databaseRef.child(self.recipeType.description).observeSingleEvent(of: .value, with: snapshot in
guard let data = snapshot.children.allObjects as? [DataSnapshot] else return
for item in data
guard let thisItem = item.value as? NSDictionary else return
let tempRecipe = Recipe()
tempRecipe.fbKey = item.key
tempRecipe.recipeImageObject = (thisItem["recipeImageFirebase"] as? String) ?? ""
tempRecipe.recipeHeaderObject = (thisItem["recipeHeaderFirebase"] as? String) ?? ""
tempRecipe.recipeTextObject = (thisItem["recipeIngredientsTextFirebase"] as? String) ?? ""
self.recipeArray.append(tempRecipe)
observer.onNext(self.recipeArray)
)
observer.onCompleted()
return Disposables.create()
)
从调用函数的部分:
func reloadContent() -> Observable<[Recipe]>
guard let fbDataHandler = fbDataHandler else return Observable.just([])
return fbDataHandler.fetchFireBaseData().do(onNext: [weak self] value in
print("WHY ISNT THIS BEING CALLED?")
self?.content.accept(value.compactMap RecipesCollectionViewCellViewModel(recipes: $0) )
)
.do(onNext:
被忽略了,我不明白为什么。完成工作:
viewModel?.reloadContent().subscribe(onCompleted:
print("THIS IS CALLED")
).disposed(by: disposeBag)
知道为什么它不起作用吗?我在这里读到:https://github.com/ReactiveX/RxSwift/issues/1212那个
a.do(onNext:
print($0) // not called ????
) <-- result is observable sequence that is discarded
但我不确定这意味着什么或如何解决它。
编辑 好的,所以这可以通过完成处理程序来解决,但是 rx 的整个想法是在没有完成处理程序的情况下做这样的事情吗?
【问题讨论】:
【参考方案1】:您的问题是您在调用observeSingleEvent(of:with:)
后立即发出onCompleted()
,而没有给闭包一个被调用的机会。解决方案是在 onNext(_:)
之后调用闭包内的 onCompleted()
。
还有许多其他问题。如果self
为空,则此 Observable 将永远不会发出任何东西,不会发出下一个事件,也不会发出任何错误或完成事件。在 create 闭包中完全引用了 self 的事实是一种糟糕的做法。而是在 create 闭包中定义 recipeArray
。
还可以将databaseRef
作为参数传递给函数,方法是使其成为高阶函数,或者使databaseRef
是其实例的类的函数和扩展。
另外,Recipe
不应该是一个类。它应该是一个结构,因为它是一个值对象。
类似这样的:
extension Reactive where Base: DatabaseRef
func fetchFireBaseData(recipeType: RecipeType) -> Observable<[Recipe]>
Observable.create observer in
base.child(recipeType.description)
.observeSingleEvent(of: .value, with: snapshot in
guard let data = snapshot.children.allObjects as? [DataSnapshot] else
observer.onError(DBError.noDataSnapshots)
return
let recipeArray = data.compactMap (item) -> Recipe? in
guard let thisItem = item.value as? NSDictionary else return nil
return Recipe(
fbKey: item.key,
recipeImageObject: (thisItem["recipeImageFirebase"] as? String) ?? "",
recipeHeaderObject: (thisItem["recipeHeaderFirebase"] as? String) ?? "",
recipeTextObject: (thisItem["recipeIngredientsTextFirebase"] as? String) ?? ""
)
observer.onNext(recipeArray)
observer.onCompleted()
)
return Disposables.create()
【讨论】:
天啊,这太有道理了!感谢您帮助我并感谢所有其他指针。它现在可以工作了 - 太棒了:)以上是关于Rx Swift 丢弃 .do(onNext: ) 我如何让它触发?的主要内容,如果未能解决你的问题,请参考以下文章
do(onNext:) 和 subscribe(onNext:) 有啥区别?