鉴于我的应用程序将从服务器下载文件,而且我只希望1下载同时进行,那么如何使用RxAlamofire完成这一工作呢?我可能只是缺少了一个Rx操作符。下面是粗略的代码:
Observable
.from(paths)
.flatMapWithIndex({ (ip, idx) -> Observable<(Int, Video)> in
let v = self.files![ip.row] as! Video
return Observable.from([(idx, v)])
})
.flatMap { (item) -> Observable<Video> in
let req = URLRequest(url: item.1.downloadURL())
return Api.alamofireManager()
.rx
.download(req, to: { (url, response) -> (destinationURL: URL, options: DownloadRequest.DownloadOptions) in
...
})
.flatMap({ $0.rx.progress() })
.flatMap { (progress) -> Observable<Float> in
// Update a progress bar
...
}
// Only propagate finished items
.filter { $0 >= 1.0 }
// Return the item itself
.flatMap { _ in Observable.from([item.1]) }
}
.subscribe(
onNext: { (res) in
...
},
onError: { (error) in
...
},
onCompleted: {
...
}
)我的问题是,a) RxAlamofire将同时下载多个项目,而b) (进度)块对于这些不同的项目被多次调用(每个条目上都有不同的进度信息,导致UI的行为有点怪异)。
如何确保下载是逐个完成而不是同时完成?
发布于 2016-11-14 08:49:13
alamofireManager().rx.download()是并发下载还是串行下载?
我不知道它是怎么做的,所以先测试一下。隔离这段代码,看看它是否一次执行多个下载。如果是这样的话,那么阅读关于串行下载而不是并发下载的文档。
如果它一次下载一个,那么它就意味着它与触发进度条更新问题的Rx代码有关。如果它一次不下载一个,那就意味着我们只需要阅读Alamofire的文档,说明如何一次下载一个。
复杂变换和副作用
需要考虑的是,您的数据流正在变得更加复杂和难以调试,因为在一个流中发生了许多事情。由于多个平面地图,可能会有更多的排放出来,影响进度条的更新。也有可能,获得可观察到的许多平面映射操作是在进度条上多次触发更新的原因。
复杂数据流
在一个数据流中,您(a)执行网络调用(b)更新进度条(c)过滤完成的视频(d),并返回到您想要的视频,在开始时使用flatMapWithIndex将id和视频模型对在一起,以便您能够返回到最后的模型。有点复杂..。我的猜测是,奇怪的进度条更新可能是由创建一个$0.rx.progress()调用时可以观察到的热点引起的。
我为我的Rx游乐场做了一个github gist,它试图为你想要做的事情建模。
在函数式反应性编程中,如果您首先定义数据流/可观察性,它将更加可读性更强,调试也更容易。在我的主旨,我开始观察和我计划如何建模下载进度。
如果RxAlamofire查询一次下载1,并且正确地显示UIProgressBar的进度值,则此代码将避免并发问题。
旁注
您需要跟踪每个下载项目的单个进度下载吗?还是希望您的进度条只增加每完成下载项目?
此外,要警惕滥用多个flatMaps 如前所述链的可能危险。
https://stackoverflow.com/questions/40519002
复制相似问题