是否有一种 Combine-y 方法来停止触发多个请求?
Is there a Combine-y way to stop multiple requests being triggered?
我目前有这样的代码...
var isFetching = false
func fetch() {
guard !isFetching else { return }
fetching = true
apiPublisher
.receive(on: .main)
.handleEvents(receiveCompletion: { [weak self] _ in
self?.fetching = false
})
.assign(to: \.foo, on: self)
.store(in: &cancellables)
}
但是我对我停止像这样发生的多个请求的方式不满意。它有效,但感觉笨重。
我觉得应该有一种更“结合”的方式来做到这一点。
有没有更多的elegant/Combine-y方法来做到这一点?
这里的问题是您在函数 (fetch()
) 中拥有整个 Publisher 订阅链,几乎任何其他代码几乎可以在任何时间从任何线程调用该函数 (fetch()
)。为了在“更多的 Combine-y”中执行此操作,您需要对其进行限制。那么问题来了,这个fetch()
函数是怎么调用的呢?如果您将所有这些呼叫站点包装在 Publisher 中,然后设置 trigger.flatMap { apiPublisher }
并设置 flatMap
以在等待当前网络请求完成时忽略事件。
像这样:
trigger
.flatMap(maxPublishers: .max(1)) {
apiPublisher
}
.receive(on: .main)
.assign(to: \.foo, on: self)
.store(in: &cancellables)
这里要注意的重要一点是你只执行这段代码一次(如果这是一个视图控制器,可能在 viewDidLoad 中执行。然后当你想发出请求时,你通过 trigger
发布者。flatMap
将确保一次只有一个 apiPublisher 订阅。
我目前有这样的代码...
var isFetching = false
func fetch() {
guard !isFetching else { return }
fetching = true
apiPublisher
.receive(on: .main)
.handleEvents(receiveCompletion: { [weak self] _ in
self?.fetching = false
})
.assign(to: \.foo, on: self)
.store(in: &cancellables)
}
但是我对我停止像这样发生的多个请求的方式不满意。它有效,但感觉笨重。
我觉得应该有一种更“结合”的方式来做到这一点。
有没有更多的elegant/Combine-y方法来做到这一点?
这里的问题是您在函数 (fetch()
) 中拥有整个 Publisher 订阅链,几乎任何其他代码几乎可以在任何时间从任何线程调用该函数 (fetch()
)。为了在“更多的 Combine-y”中执行此操作,您需要对其进行限制。那么问题来了,这个fetch()
函数是怎么调用的呢?如果您将所有这些呼叫站点包装在 Publisher 中,然后设置 trigger.flatMap { apiPublisher }
并设置 flatMap
以在等待当前网络请求完成时忽略事件。
像这样:
trigger
.flatMap(maxPublishers: .max(1)) {
apiPublisher
}
.receive(on: .main)
.assign(to: \.foo, on: self)
.store(in: &cancellables)
这里要注意的重要一点是你只执行这段代码一次(如果这是一个视图控制器,可能在 viewDidLoad 中执行。然后当你想发出请求时,你通过 trigger
发布者。flatMap
将确保一次只有一个 apiPublisher 订阅。