【问题标题】:RxSwift: delay observable until another observable is finished?RxSwift:延迟 observable 直到另一个 observable 完成?
【发布时间】: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 }
    }

但是,上面的代码会加载图像两次:一次是获取所有帖子,一次是我将帖子绑定到表格视图。怎么处理?

【问题讨论】:

  • 你能解释一下你在现有代码中所做的事情的原因吗?我了解您想将帖子映射到他们的图像,为什么要拍摄最后一张图像,然后将其映射回帖子?
  • 这是一种等待图片加载的丑陋方式
  • 嗯,我得到了这么多,但它是如何工作的?
  • 如何绑定到表格视图?

标签: swift reactive-programming rx-swift


【解决方案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&lt;T&gt;] 转换为Observable&lt;[T]&gt;

操作员获取 Observables 数组,订阅所有这些,等待它们全部完成,然后发出一个包含所有收集值数组的事件。 (之后,每次更新其中一个项目时,它都会发出一个新数组,但这与这里无关。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-03-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多