【发布时间】:2021-03-17 18:31:53
【问题描述】:
我有两个 URL 列表,它们返回一些图像链接。 列表被传递到未来,如
static func loadRecentEpisodeImagesFuture(request: [URL]) -> AnyPublisher<[RecentEpisodeImages], Never> {
return Future { promise in
print(request)
networkAPI.recentEpisodeImages(url: request)
.sink(receiveCompletion: { _ in },
receiveValue: { recentEpisodeImages in
promise(.success(recentEpisodeImages))
})
.store(in: &recentImagesSubscription)
}
.eraseToAnyPublisher()
}
调用者:
/// Get a list of image sizes associated with a featured episode .
func featuredEpisodeImages(featuredUrl: [URL]) -> AnyPublisher<[FeaturedEpisodeImages], Error> {
let featuredEpisodesImages = featuredUrl.map { (featuredUrl) -> AnyPublisher<FeaturedEpisodeImages, Error> in
return URLSession.shared
.dataTaskPublisher(for: featuredUrl)
.map(\.data)
.decode(type: FeaturedEpisodeImages.self, decoder: decoder)
.receive(on: networkApiQueue)
.catch { _ in Empty<FeaturedEpisodeImages, Error>() }
.print("###Featured###")
.eraseToAnyPublisher()
}
return Publishers.MergeMany(featuredEpisodesImages).collect().eraseToAnyPublisher()
}
/// Get a list of image sizes associated with a recent episode .
func recentEpisodeImages(recentUrl: [URL]) -> AnyPublisher<[RecentEpisodeImages], Error> {
let recentEpisodesImages = recentUrl.map { (recentUrl) -> AnyPublisher<RecentEpisodeImages, Error> in
return URLSession.shared
.dataTaskPublisher(for: recentUrl)
.map(\.data)
.decode(type: RecentEpisodeImages.self, decoder: decoder)
.receive(on: networkApiQueue)
.catch { _ in Empty<RecentEpisodeImages, Error>() }
.print("###Recent###")
.eraseToAnyPublisher()
}
return Publishers.MergeMany(recentEpisodesImages).collect().eraseToAnyPublisher()
}
并附加到应用状态:
/// Takes an action and returns a future mapped to another action.
static func recentEpisodeImages(action: RequestRecentEpisodeImages) -> AnyPublisher<Action, Never> {
return loadRecentEpisodeImagesFuture(request: action.request)
.receive(on: networkApiQueue)
.map({ images in ResponseRecentEpisodeImages(response: images) })
.replaceError(with: RequestFailed())
.eraseToAnyPublisher()
}
看来:
return Publishers.MergeMany(recentEpisodes).collect().eraseToAnyPublisher()
没有给我一个可靠的下游值,因为最后完成的响应会覆盖较早的响应。
我能够记录这两个系列请求的响应。两者都在处理正确的数组并返回正确的 json。
我想要类似的东西:
return recentEpisodeImages
但目前这给了我错误
无法将“[AnyPublisher
]”类型的返回表达式转换为“AnyPublisher”类型的返回表达式
如何收集内部发布者的值并将其返回为
AnyPublisher<[RecentEpisodeImages], Error>
【问题讨论】:
-
为什么要配置双向合并?这是没有意义的。还有这里的目标是什么?这些是相同的网址吗?不同的 URL 集?响应顺序被打乱了怎么办?您是否不在乎失去与每个图像来自哪个 URL 的连接?你会不加选择地混合不同类型的图像吗?
-
好吧,你还没有解释你想要做什么。这个问题毫无意义:“我怎样才能将这些流的结果分开?”如果你想让它们分开,你为什么要合并它们?深呼吸,然后解释手头的整个问题:输入和期望的输出。
-
是的,合并肯定是问题所在,函数采用两个不同的 URL 数组并返回两个不同的 URL 数组。它们返回的顺序无关紧要。我需要将 Publishers.MergeMany() 替换为抓取 url.map 的结果而不与其范围之外的流合并的东西。
-
但是你为什么不能回答我的问题呢?目标是什么?图像流?还是由一组图像组成的流?还是什么?
-
我需要输入 [URL] 中的 AnyPublisher 类型。流中的数组是一个包含图像链接的 json 数组。我需要能够将此流传递给其他一些流,并且这些流需要停止相互覆盖。
标签: swift asynchronous combine urlsession