我有一个出版商,当水槽,扫描一个无线网络列表。我只想扫描大约10秒然后停止。
在发布服务器调用链中有什么方法可以这样做吗?
发布于 2021-10-29 00:43:44
这个接线员会做这件事的。
import PlaygroundSupport
import Foundation
import Combine
let page = PlaygroundPage.current
page.needsIndefiniteExecution = true
extension Publisher {
func stopAfter<S>(_ interval: S.SchedulerTimeType.Stride, tolerance: S.SchedulerTimeType.Stride? = nil, scheduler: S, options: S.SchedulerOptions? = nil) -> AnyPublisher<Output, Failure> where S: Scheduler {
prefix(untilOutputFrom: Just(()).delay(for: interval, tolerance: tolerance, scheduler: scheduler, options: nil))
.eraseToAnyPublisher()
}
}
let source = Timer.publish(every: 1, tolerance: nil, on: RunLoop.main, in: .default, options: nil)
.autoconnect()
.eraseToAnyPublisher()
let cancellable = source
.stopAfter(10, scheduler: DispatchQueue.main)
.sink(receiveValue: { print($0) })
发布于 2021-10-30 19:16:06
您可以使用超时()操作符:
如果上游发布服务器超过指定的时间间隔而不生成元素,则终止发布。
wifiScannerPublisher
.timeout(.seconds(waitTime), scheduler: DispatchQueue.main, options: nil, customError:nil)
.sink(
receiveCompletion: { print("completion: \($0), at: \(Date())") },
receiveValue: { print("wifi: \($0)") }
)
但是,如果您的发布者经常发出事件,并且您只是想在经过一段时间之后停止它,那么丹尼尔氏答案可能是最好的方法。
尽管如此,我将通过使用timeout()
和scan()
的timeout()
扩展来自己添加一个解决方案
extension Publisher {
func stopAfter(_ interval: TimeInterval) -> AnyPublisher<Output, Failure> {
self
.timeout(.seconds(interval), scheduler: DispatchQueue.main)
.scan((Date()+interval, nil)) { ($0.0, $1) }
.prefix(while: { Date() < $0.0 })
.map { $0.1! }
.eraseToAnyPublisher()
}
}
上面的发布者将携带超时日期,一旦到达该日期,它将停止。需要使用map
来丢弃携带在项目中的额外Date
。
用法:
wifiListPublisher.stopAfter(10)
.sink(...)
https://stackoverflow.com/questions/69762275
复制相似问题