RxSwift:延迟 observable 直到另一个 observable 完成?
Posted
技术标签:
【中文标题】RxSwift:延迟 observable 直到另一个 observable 完成?【英文标题】:RxSwift: delay observable until another observable is finished? 【发布时间】:2019-02-01 15:54:22 【问题描述】:我从服务器加载帖子并希望仅在他们的图片全部加载时显示。 这是我想要做的:
postsRepository
.fetchPosts()
.flatMap posts -> Observable<[Post]> in
return Observable.merge(posts.map( /* Code that returns Observable<UIImage> */ ))
.takeLast(1)
.map _ in posts
但是,上面的代码会加载图像两次:一次是获取所有帖子,一次是我将帖子绑定到表格视图。怎么处理?
【问题讨论】:
你能解释一下你在现有代码中所做的事情的原因吗?我了解您想将帖子映射到他们的图像,为什么要拍摄最后一张图像,然后将其映射回帖子? 这是一种等待图片加载的丑陋方式 嗯,我得到了这么多,但它是如何工作的? 如何绑定到表格视图? 【参考方案1】:这是一个有趣的...
let postsWithImages = postsRepository
.fetchPosts()
.flatMap posts in
Observable.combineLatest(
posts
.map $0.imageURL
.map URLSession.shared.rx.data(request: URLRequest(url: $0))
.map UIImage(data: $0)
.catchErrorJustReturn(nil)
)
.map zip(posts, $0)
.map $0.map (post: $0.0, image: $0.1)
如果您对使用Zip2Sequence
感到满意,那么最后一个map
可能不是绝对必要的。
以上假设Post
具有imageURL: URL
属性。
让我们把它清理一下:
let postsWithImages = postsRepository
.fetchPosts()
.flatMap posts in
Observable.combineLatest(
posts
.map $0.imageURL
.map URLSession.shared.rx.image(for: $0)
)
.map zip(posts, $0)
.map $0.map (post: $0.0, image: $0.1)
以上需要一个新功能:
extension Reactive where Base == URLSession
func image(for url: URL) -> Observable<UIImage?>
return data(request: URLRequest(url: url))
.map UIImage(data: $0)
.catchErrorJustReturn(nil)
我想我会添加一些解释。正如我在文章Recipes for Combining Observables in RxSwift 中提到的,这里的神奇之处在于使用combineLatest
将[Observable<T>]
转换为Observable<[T]>
。
操作员获取 Observables 数组,订阅所有这些,等待它们全部完成,然后发出一个包含所有收集值数组的事件。 (之后,每次更新其中一个项目时,它都会发出一个新数组,但这与这里无关。)
【讨论】:
以上是关于RxSwift:延迟 observable 直到另一个 observable 完成?的主要内容,如果未能解决你的问题,请参考以下文章
RxSwift - 确定 Observable 是不是已被释放