我已经编写了一个Rx查询来在计时器中执行异步任务。这也处理我需要丢弃其响应稍后的订单请求的场景。这是用C#编写的:
public static IObservable<T> PollingAync<T> (Func<Task<T>> AsyncCall, double TimerDuration)
{
return Observable
.Create<T>(o =>
{
var z = 0L;
return
Observable
.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(TimerDuration))
.SelectMany(nr =>
Observable.FromAsync<T>(AsyncCall),
(nr, obj) => new { nr, obj})
.Do(res => z = Math.Max(z, res.nr))
.Where(res => res.nr >= z)
.Select(res => res.obj)
.Subscribe(o);
});
}
我希望在swift中编写相同的实现来处理异步任务,并且还丢弃其响应稍后的订单请求。我想在swift3.0中写这个
由于我是swift的新手,请帮助告诉我如何在不使用Rx 的快速中获得相同的结果。
答案 0 :(得分:2)
这是一个有趣的问题要回答......
enum Result<T> {
case success(T)
case failure(Error)
}
typealias Cancel = () -> Void
func pollingAsync<T>(asyncCall: @escaping (@escaping (Result<T>) -> Void) -> Cancel, duration: TimeInterval, callback: @escaping (Result<T>) -> Void) -> Cancel {
let timer = DispatchSource.makeTimerSource(queue: DispatchQueue.main)
timer.scheduleRepeating(deadline: .now(), interval: .milliseconds(Int(duration * 1000)), leeway: .milliseconds(10))
var asyncCallCancel: Cancel? = nil
timer.setEventHandler {
asyncCallCancel?()
asyncCallCancel = asyncCall {
callback($0)
}
}
timer.resume()
return {
asyncCallCancel?()
timer.cancel()
}
}
要使用上述内容,您可以执行以下操作:
let cancel = pollingAsync(asyncCall: myAsyncOp, duration: 2.0) {
print($0)
}
如果您忘记了从此功能返回的Cancel
对象,您将无法关闭计时器。
作为参考,这是RxSwift中的等效代码:
func pollingAsync<T>(asyncCall: @escaping () -> Observable<T>, duration: TimeInterval) -> Observable<Event<T>> {
return Observable<Int>.interval(duration, scheduler: MainScheduler.instance)
.flatMapLatest { _ in
asyncCall().materialize().filter { !$0.isCompleted }
}
}