RxSwift-方法在可观察到的对象被调用之前返回

时间:2019-12-11 21:48:05

标签: swift observable system.reactive

这是我要完成的工作的基本流程:

  1. Grab最近使用Spotify API播放了曲目
  2. 对于每个曲目,获取关联的演出者API端点
  3. 对于每个演出者API端点,获取其个人资料图片的关联网址
  4. 将每个曲目的艺术家图像组合到URL数组中
  5. 使用新形成的URL数组创建一个新的跟踪对象。

在深入探讨问题之前,下面是基础代码。

这是当前可观察的trackCollections的样子:

trackCollections = sessionService.getRecentlyPlayedTracks(limit: 10)
        .flatMapLatest { [unowned self] tracks -> Observable<[RecentlyPlayedTrack]> in
            var updatedTracks = [RecentlyPlayedTrack]()

            for track in tracks {
                self.getArtistImages(artistURLs: track.artistURLs)
                    .bind(onNext: { imageURLs in
                        let updatedTrack = RecentlyPlayedTrack(trackName: track.trackName, albumName: track.albumName, artistURLs: imageURLs, duration: track.duration, playedFrom: track.playedFrom, playedAt: track.playedFrom, externalURL: track.externalURL)

                        Logger.info("Creating new updated track: \(updatedTrack)")
                        updatedTracks.append(updatedTrack)
                    })
                    .disposed(by: self.disposeBag)
            }

            return Observable.just(updatedTracks)
    }

返回艺术家图像的帮助方法:

private func getArtistImages(artistURLs: [URL]) -> Observable<[URL]> {
    var urls = [URL]()
    Logger.info("\(urls.count) - \(artistURLs.count)")
    for url in artistURLs {
        self.sessionService.getArtist(href: url)
            .map { $0.image }
            .bind(onNext: {
                Logger.info("Artist Image: \($0.absoluteString)")
                urls.append($0)
            })
            .disposed(by: self.disposeBag)
    }

    return Observable.just(urls)
}

这是运行时的输出:

2019-12-11 13:17:58 | INFO | Creating new updated track: RecentlyPlayedTrack(trackName: 
"Becalm", albumName: "Solo", artistURLs: [], duration: "2:29", playedFrom: "Playlist", 
playedAt: "Playlist", externalURL: https://open.spotify.com/track/4N9UKWy0TLiwNEuzeynWiU)
2019-12-11 13:17:58 | INFO | Creating new updated track: RecentlyPlayedTrack(trackName: 
"The Piano Inside", albumName: "The Piano Inside", artistURLs: [], duration: "3:11", 
playedFrom: "Playlist", playedAt: "Playlist", externalURL: 
https://open.spotify.com/track/0BtymruMtXTo6vdk4LH4aB)
2019-12-11 13:17:58 | INFO | Creating new updated track: RecentlyPlayedTrack(trackName: "Aoyama 
Bochi", albumName: "Aoyama Bochi", artistURLs: [], duration: "2:03", playedFrom: "Playlist", 
playedAt: "Playlist", externalURL: https://open.spotify.com/track/6aLLf5UU8GivpvjLxdOog1)
2019-12-11 13:17:58 | INFO | Artist Image: 
https://i.scdn.co/image/2d4572b6761c8340118405ae5fb07a3c341162e8
2019-12-11 13:17:58 | INFO | Artist Image:      
https://i.scdn.co/image/ab67616d0000b2732b3835d0c00e8232df3b035d
2019-12-11 13:17:58 | INFO | Artist Image: 
https://i.scdn.co/image/ab67616d0000b273f84ddc43f770853051c2b698

问题:

  • 如您所见,我得到的输出是错误的:每次运行程序时,返回美工图像(URL)的函数将返回一个空数组。只有在创建跟踪对象之后,才查询艺术家图像(控制台中的最后3行)。当在trackCollections observable中调用bind时,此时的imageURLs为空。

为什么我认为这种情况正在发生:

  • 我在循环中为艺术家的url每次迭代创建的可观察对象并没有立即被调用;可能是这样,我认为它被调用的可能性更大,但是它仍然太慢,以至于在将艺术家的图像附加到数组之前该方法返回一个空数组。因为我是RxSwift的新手,所以我想了解一些有关如何使用Rx进行优化的指南。

您应该了解的事情:

  • sessionService的getRecentlyplayedtracks方法返回Observable <[RecentlyPlayedTracks]>
  • sessionService的getArtist方法返回Observable
  • 确实,这里的问题出在助手方法上。我如何才能使该方法仅在url数组包含所有url之后返回(当然使用Rx)?
  • 是否有更好的方法来编写辅助方法循环,​​例如使用map或其他转换运算符?

0 个答案:

没有答案