ios - 在 RxSwift 的 for 循环中调用多个 API 请求的最佳方式
问题描述
我必须使用 for 循环进行几次 api 调用(大约 100 次),完成此操作后,我需要完成 Observable。我使用它如下:
func getMaterialInfo(materialNo:[String]) -> Observable<[String: Material]>{
return Observable.create({ (observable) -> Disposable in
for (index,mat) in materialNo.enumerated(){
// Pass the material number one by one to get the Material object
self.getMaterialInfo(materialNo: mat).subscribe(onNext: { material in
var materialDict: [String: Material] = [:]
materialDict[material.materialNumber] = material
observable.onNext(materialDict)
if index == (materialNo.count-1){
observable.onCompleted()
}
}, onError: { (error) in
observable.onError(error)
}, onCompleted: {
}).disposed(by: self.disposeBag)
}
return Disposables.create()
})
}
虽然循环工作正常并且 observable.onCompleted() 被调用,但调用者方法没有收到它。我这样称呼它:
private func getImage(materialNo:[String]){
if materialNo.isEmpty {
return
}
var dictMaterials = [String:String]()
materialService.getMaterialInfo(materialNo: materialNo).subscribe(onNext: { (materials) in
for (key,value) in materials{
if (value.imageUrl != nil){
dictMaterials[key] = value.imageUrl
}
}
}, onError: { (error) in
}, onCompleted: {
self.view?.updateToolImage(toolImageList: dictMaterials)
}, onDisposed: {}).disposed(by: disposeBag)
}
Rx 的 OnCompleted 块未执行。我该如何解决?
解决方案
编辑(3 月 5 日)
我重新审视了这个答案,因为当我编写下面的代码示例时,我不确定我的大脑在做什么。我会做这样的事情:
func getMaterialInfo(materialNo: String) -> Observable<[String: Material]> {
// ...
}
func getMaterialInfo(materialNumbers:[String]) -> Observable<[String: Material]>{
let allObservables = materialNumbers
.map { getMaterialInfo(materialNo: $0) }
return Observable.merge(allObservables)
}
原始答案
从您的代码中,我解释说所有单独getMaterialInfo
的调用都是同时完成的。基于此,我将重写您的getMaterialInfo(:[_])
方法以使用.merge
运算符。
func getMaterialInfo(materialNo:[String]) -> Observable<[String: Material]>{
return Observable.create({ (observable) -> Disposable in
// a collection of observables that we haven't yet subscribed to
let allObservables = materialNo
.map { getMaterialInfo(materialNo: $0) }
return Observable.merge(allObservables)
}
return Disposables.create()
}
请注意,使用merge
同时订阅所有 observable,同时触发 100 个网络请求。对于顺序订阅,请concat
改用!
推荐阅读
- amazon-athena - 在多种产品中获得唯一客户数量的最佳方式
- php - 使用 php5.6 安装 debian 拉伸
- c# - 身份验证过滤器不适用于 Web API 中的授权过滤器
- android - 如何使用 volley 将多个图像存储在 Array 和单个 ImageView 上
- c++ - 使用
当主要可执行文件不是 .NET 时 - maven - maven repo 中的 Athena JDBC Driver 2.0.7?
- html - 在 Kendo-Grid 中只有特定的行是可编辑的
- sql - 如何根据另一列的唯一ID从一列中获取最大值、平均值、最小值、计数
- c# - 关于 2D 列表 C# 的问题
- flutter - Flutter使用http检索后台接口,报错:FormatException: Invalid radix-10 number