Ios 合并:如何取消平面图';编辑出版商
新的组合和反应式编程在这里,所以帮助是非常感谢 我有以下场景:我想构建一个用户界面,用户可以通过页面上的各种“过滤”按钮过滤内容。当用户点击其中一个按钮时,我需要发出一个API请求来获取数据 现在,我有一个发布者为我提供这些选择的“状态”,我的代码结构如下:Ios 合并:如何取消平面图';编辑出版商,ios,swift,reactive-programming,combine,Ios,Swift,Reactive Programming,Combine,新的组合和反应式编程在这里,所以帮助是非常感谢 我有以下场景:我想构建一个用户界面,用户可以通过页面上的各种“过滤”按钮过滤内容。当用户点击其中一个按钮时,我需要发出一个API请求来获取数据 现在,我有一个发布者为我提供这些选择的“状态”,我的代码结构如下: state .publisher /* sends whenever 'state' updates behind the scenes */ .debounce(for: 1
state
.publisher /* sends whenever 'state' updates behind the scenes */
.debounce(for: 1.0, scheduler: DispatchQueue.main)
.map { /* create some URL request */ }
.flatMap {
URLSession.shared.dataTaskPublisher(for: someRequest)
.map { $0.data }
.decode(type: MyResponseType.self, decoder: JSONDecoder())
}.sink(receiveCompletion: { (completion) in
/// cancelled
}) { (output) in
/// go show my results
/// Ideally, this is only called when the most recent API call finishes!
}.store(in: &cancellables)
但是,此实现在以下场景中有一个bug:如果一个事件通过flatMap发出请求,并且后续事件在网络调用完成之前执行相同操作,那么我们将调用完成处理程序两次
最好是,我们以某种方式取消了内部管道,因此我们只使用最近的事件执行完成处理程序
当新事件进入管道时,如何“取消”该内部管道(由dataTaskPublisher启动的管道),而不拆除外部管道?您不需要
flatMap
。您需要切换到最新的。将flatMap
更改为普通map
,然后在其后面添加.switchToLatest()
。由于switchToLatest
需要匹配故障类型,因此您可能还需要使用maperor
。decode
操作符生成故障类型Error
,因此您可以将Error
映射到Error
例如:
state
.publisher /* sends whenever 'state' updates behind the scenes */
.debounce(for: 1.0, scheduler: DispatchQueue.main)
.map { makeURLRequest(from: $0) }
.map({ someRequest in
URLSession.shared.dataTaskPublisher(for: someRequest)
.map { $0.data }
.decode(type: MyResponseType.self, decoder: JSONDecoder())
})
.mapError { $0 as Error }
.switchToLatest()
.sink(
receiveCompletion: ({ (completion) in
print(completion)
/// cancelled
}),
receiveValue: ({ (output) in
print(output)
/// go show my results
/// Ideally, this is only called when the most recent API call finishes!
}))
.store(in: &cancellables)
您不需要flatMap
。您需要切换到最新的。将flatMap
更改为普通map
,然后在其后面添加.switchToLatest()
。由于switchToLatest
需要匹配故障类型,因此您可能还需要使用maperor
。decode
操作符生成故障类型Error
,因此您可以将Error
映射到Error
例如:
state
.publisher /* sends whenever 'state' updates behind the scenes */
.debounce(for: 1.0, scheduler: DispatchQueue.main)
.map { makeURLRequest(from: $0) }
.map({ someRequest in
URLSession.shared.dataTaskPublisher(for: someRequest)
.map { $0.data }
.decode(type: MyResponseType.self, decoder: JSONDecoder())
})
.mapError { $0 as Error }
.switchToLatest()
.sink(
receiveCompletion: ({ (completion) in
print(completion)
/// cancelled
}),
receiveValue: ({ (output) in
print(output)
/// go show my results
/// Ideally, this is only called when the most recent API call finishes!
}))
.store(in: &cancellables)