Swift 5.5 中的循环函数使用 async/await
Recurring function in Swift 5.5 using async/await
我想在函数完成 5 秒后继续触发它。
以前我会在函数末尾使用它:
Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { self.function() }
但我想使用 Swift 5.5
的 async/await
。
如果我使用这样的东西:
func loadInfo() async {
async let info = someOtherAsyncFunc()
self.info = try? await info
await Task.sleep(5_000_000_000)
await loadInfo()
}
我收到一条警告,说 Function call causes an infinite recursion
并且它不是真的可以取消。
编译正常:
func loadInfo() async {
Task {
async let info = someOtherAsyncFunc()
self.info = try? await info
await Task.sleep(5_000_000_000)
if Task.isCancelled {
print("Cancelled")
}
else
{
print("Not cancelled")
await loadInfo()
}
}
}
虽然它每 5 秒触发一次,但当我的 SwiftUI
视图被关闭时它会保持 运行。
我开始使用:
.onAppear {
loadInfo()
}
因为在同一个 Task
而不是 detached
上都是 运行,当视图被移除时,它不应该全部取消吗?
使用 async/await
实现此目的的现代方法是什么?
您可以将任务保存在 @State
变量中,然后在 onDisappear(perform:)
视图消失时取消它。
工作示例:
struct ContentView: View {
@State private var info: String?
@State private var currentTask: Task<Void, Never>?
var body: some View {
NavigationView {
VStack {
Text(info ?? "None (yet)")
.onAppear(perform: loadInfo)
.onDisappear(perform: cancelTask)
NavigationLink("Other view") {
Text("Some other view")
}
}
.navigationTitle("Task Test")
}
.navigationViewStyle(.stack)
}
private func loadInfo() {
currentTask = Task {
async let info = someOtherAsyncFunc()
self.info = try? await info
await Task.sleep(5_000_000_000)
guard !Task.isCancelled else { return }
loadInfo()
}
}
private func cancelTask() {
print("Disappear")
currentTask?.cancel()
}
private func someOtherAsyncFunc() async throws -> String {
print("someOtherAsyncFunc ran")
return "Random number: \(Int.random(in: 1 ... 100))"
}
}
我想在函数完成 5 秒后继续触发它。
以前我会在函数末尾使用它:
Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { self.function() }
但我想使用 Swift 5.5
的 async/await
。
如果我使用这样的东西:
func loadInfo() async {
async let info = someOtherAsyncFunc()
self.info = try? await info
await Task.sleep(5_000_000_000)
await loadInfo()
}
我收到一条警告,说 Function call causes an infinite recursion
并且它不是真的可以取消。
编译正常:
func loadInfo() async {
Task {
async let info = someOtherAsyncFunc()
self.info = try? await info
await Task.sleep(5_000_000_000)
if Task.isCancelled {
print("Cancelled")
}
else
{
print("Not cancelled")
await loadInfo()
}
}
}
虽然它每 5 秒触发一次,但当我的 SwiftUI
视图被关闭时它会保持 运行。
我开始使用:
.onAppear {
loadInfo()
}
因为在同一个 Task
而不是 detached
上都是 运行,当视图被移除时,它不应该全部取消吗?
使用 async/await
实现此目的的现代方法是什么?
您可以将任务保存在 @State
变量中,然后在 onDisappear(perform:)
视图消失时取消它。
工作示例:
struct ContentView: View {
@State private var info: String?
@State private var currentTask: Task<Void, Never>?
var body: some View {
NavigationView {
VStack {
Text(info ?? "None (yet)")
.onAppear(perform: loadInfo)
.onDisappear(perform: cancelTask)
NavigationLink("Other view") {
Text("Some other view")
}
}
.navigationTitle("Task Test")
}
.navigationViewStyle(.stack)
}
private func loadInfo() {
currentTask = Task {
async let info = someOtherAsyncFunc()
self.info = try? await info
await Task.sleep(5_000_000_000)
guard !Task.isCancelled else { return }
loadInfo()
}
}
private func cancelTask() {
print("Disappear")
currentTask?.cancel()
}
private func someOtherAsyncFunc() async throws -> String {
print("someOtherAsyncFunc ran")
return "Random number: \(Int.random(in: 1 ... 100))"
}
}