我决定在 Combine 框架中使用 async/await。 我在 Future 类上使用了一个扩展,并在其中放置了一个 Task 块。 看起来没问题,我得到了结果或错误,但我对此有疑问,如果我只想取消我的异步函数的进度,我就取消了发布者。
我在扩展下面使用,我在 https://tanaschita.com/20220822-bridge-async-await-to-combine-future/
上学习extension Future where Failure == Error {
convenience init(taskPriority: TaskPriority? = nil, asyncFunc: @escaping () async throws -> Output) {
self.init { promise in
Task(priority: taskPriority) {
do {
let result = try await asyncFunc()
promise(.success(result))
} catch {
promise(.failure(error))
}
}
}
}
}
并编写两个辅助函数,用于将数据保存到核心数据中(例如):
func saveIntoCoreData() throws {
throw DatabaseError.canNotSave
}
func doSomeThing() async throws -> String {
return try await withCheckedThrowingContinuation { continuation in
do {
Thread.sleep(forTimeInterval: 5)
try saveIntoCoreData()
continuation.resume(with: .success("Result"))
} catch {
continuation.resume(with: .failure(error))
}
}
}
最后,我用 Future 调用了这些方法,我希望得到一个取消错误并停止运行以将数据保存到核心数据中,但只是从发布者那里得到一个取消事件,数据被保存到核心数据中。
cancelable = Future(taskPriority: .userInitiated) { [weak self] in
return try await self?.doSomeThing()
}.eraseToAnyPublisher()
.sink { completion in
switch completion {
case .finished:
print("Finished")
case .failure(let error):
print(error.localizedDescription)
}
} receiveValue: { value in
print("result: \(value)")
}
DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) {
self.cancelable?.cancel()
}
我试过
Task.checkCancellation()
但任务没有被取消,也没有成功。
有没有人有停止任务的想法?
Futures 不能被取消,但是 Publisher 可以。
然后你可以:
extension AnyPublisher where Failure == Error {
init(taskPriority: TaskPriority? = nil, asyncFunc: @escaping () async throws -> Output) {
self.init { subscriber in
let task = Task(priority: taskPriority) {
do {
subscriber.send(try await asyncFunc())
subscriber.send(completion: .finished)
} catch {
subscriber.send(completion: .failure(error))
}
}
return AnyCancellable { task.cancel() }
}
}
}