如何在 Swift 5.5 中将 async/await 与 SwiftUI 一起使用?

Kay*_*try 10 async-await swift swift5 swiftui

我一直在测试 Swift 5.5 版本中预览的异步/等待功能,但我无法从异步函数收集结果并使用 SwiftUI 显示它们。这是我的代码:

import SwiftUI

struct AsyncTestView: View {
    @State var text: String?

    // Async function
    func asyncGetText() async -> String {
        Thread.sleep(forTimeInterval: 10)
        return "My text"
    }
    
    // Stores the result of async function
    func fetchText() async {
        let text = await asyncGetText()
        DispatchQueue.main.async {
            self.text = text
        }
    }
    
    var body: some View {
        Text(text ?? "Loading")
            .onAppear(perform: fetchText)
    }
}
Run Code Online (Sandbox Code Playgroud)

这会导致以下错误:

在不支持并发的函数中调用 'async'
将 'async' 添加到函数 'fetchText()' 以使其异步

添加asyncfetchText()函数然后会导致函数出现以下错误.onAppear()

从“() async -> ()”类型的“async”函数到同步函数类型“() -> Void”的无效转换

本文中,他们使用@asyncHandler标记来注释fetchText函数,但这会导致警告:'@asyncHandler' has been removed from the language'

小智 14

我同意 @peter-friese 的答案,但会为那些阅读本文的人添加从同步桥接到异步时语法的变化:

新语法:

Task {
   someState = await someAsyncFunction()
}
Run Code Online (Sandbox Code Playgroud)

替换此语法:

async {
   someState = await someAsyncFunction()
}
Run Code Online (Sandbox Code Playgroud)

...并且Task()初始化程序可以接受优先级参数:

Task(priority: .userInitiated) {
   someState = await someAsyncFunction()
}
Run Code Online (Sandbox Code Playgroud)


Pet*_*ese 12

我是你引用的文章的作者。

正如在 SwiftUI发现并发中所讨论的,视图可以使用 new.task { }.refreshable { }修饰符来异步获取数据。

因此,您现在可以使用以下选项来调用异步代码:

func someSyncMethod() {
  doSomeSyncWork()
  async {
    await methodThatIsAsync()
  }
}
Run Code Online (Sandbox Code Playgroud)
List {
}
.task {
  await methodThatIsAsync()
}
Run Code Online (Sandbox Code Playgroud)
List {
}
.refreshable {
  await methodThatIsAsync()
}
Run Code Online (Sandbox Code Playgroud)

如果您使用单独的视图模型,请确保将其标记为@MainActor确保在主要角色上执行属性更新。

我更新了我文章的代码:https : //github.com/peterfriese/Swift-Async-Await-Experiments

  • 我完全经历过真正执行此类操作的代码(想想相互依赖的连续在线数据库调用)。组合框架最终拯救了我,但 async/await _真的_会拯救我。事实是,95% 的程序员似乎甚至不理解异步的含义(因此我的 http://www.programmingios.net/what-asynchronous-means/),而有了 async/await,他们就不必理解了! (3认同)

Nun*_*ves 11

根据 WWDC 会话Meet async/await in Swift WWDC 中的新信息,在 23m:28s 现在使用:

async {
   await someAsyncFunction()
}
Run Code Online (Sandbox Code Playgroud)

会议截图。

在此处输入图片说明