因此,尽管我对这可能很重要的上下文发表了评论,但这就是我将如何异步转换[A]
为[B]
使用 ReactiveSwift。请注意,我没有机会测试此代码,但它应该涵盖基本思想:
// This function takes an `NSURL` and creates an asynchronous `SignalProducer` to
// download an image from that URL or yields `nil` if there is an error.
func downloadImage(url: URL) -> SignalProducer<UIImage?, NoError> {
let request = URLRequest(url: url)
return URLSession.shared.reactive.data(with: request)
.map { (data, response) -> UIImage? in UIImage(data: data) }
.flatMapError { _ in SignalProducer<UIImage?, NoError>(value: nil) }
}
func convertAToB(_ a: A) -> SignalProducer<B, NoError> {
let imgDownload = downloadImage(url: a.imageURL)
let thumbDownload = downloadImage(url: a.thumbnailURL)
return SignalProducer<UIImage?, NoError>.combineLatest(imgDownload, thumbDownload)
.map { images in
return B(name: a.name, image: images.0, thumbnail: images.1)
}
}
func convertAllAsToBs(_ inputs: [A]) -> SignalProducer<[B], NoError> {
return SignalProducer<A, NoError>(values: inputs)
.flatMap(.concat, convertAToB)
.collect()
}
let inputs: [A] = ...
convertAllAsToBs(inputs).startWithValues { outputs in
// `outputs` is [B]
}
编辑:
为了使这个答案与@PhilippeC 的 RxSwift 答案相提并论,这里总结了每个 ReactiveSwift 操作员正在做的事情:
SignalProducer.init(values:)
相当于 RxSwift 的Observable.from
. 它创建了一个生产者,将序列的每个值作为一个单独的事件发送。
collect
相当于 RxSwift 的toArray
. 它从源生产者收集每个值,并在源生产者完成后将它们发送到单个数组中。
flatMap
convertAToB
为每个传入启动生产者A
,并根据指定合并结果FlattenStrategy
。在这种情况下,我使用.concat
了 ,这使得它等同于 RxSwift 的concatMap
连接每个结果并保留@PhilippeC 在他的回答中描述的顺序。