How to call async throwing functions 如何调用异步 throwing 函数

How to call async throwing functions 如何调用异步 throwing 函数

温馨提示:本文最后更新于2025-02-07 10:11:57,某些文章具有时效性,若有错误或已失效,请在下方留言

Just like their synchronous counterparts, Swift’s async functions can be throwing or non-throwing depending on how you want them to behave. However, there is a twist: although we mark the function as being async throws, we call the function using try await – the keyword order is flipped.
就像它们的同步对应项一样,Swift 的异步函数可以是 throw 函数,也可以是非 throwing,这取决于你希望它们的行为方式。但是,有一个转折点:虽然我们将函数标记为async throws,但我们使用 try await 调用函数 – 关键字顺序是颠倒的。

To demonstrate this in action, here’s a fetchFavorites() method that attempts to download some JSON from my server, decode it into an array of integers, and return the result:
为了在实践中演示这一点,下面是一个 fetchFavorites() 方法,它尝试从我的服务器下载一些 JSON,将其解码为整数数组,然后返回结果:

func fetchFavorites() async throws -> [Int] {
    let url = URL(string: "https://hws.dev/user-favorites.json")!
    let (data, _) = try await URLSession.shared.data(from: url)
    return try JSONDecoder().decode([Int].self, from: data)
}

if let favorites = try? await fetchFavorites() {
    print("Fetched \(favorites.count) favorites.")
} else {
    print("Failed to fetch favorites.")
}

Both fetching data and decoding it are throwing functions, so we need to use try in both those places. Those errors aren’t being handled in the function, so we need to mark fetchFavorites() as also being throwing so Swift can let any errors bubble up to whatever called it.
获取数据和解码数据都是 throw 函数,因此我们需要在这两个地方都使用 try。这些错误没有在函数中被处理,所以我们需要将 fetchFavorites() 标记为也被抛出,这样 Swift 就可以让任何错误冒泡到调用它的地方。

Notice that the function is marked async throws but the function calls are marked try await – like I said, the keyword order gets reversed. So, it’s “asynchronous, throwing” in the function definition, but “throwing, asynchronous” at the call site. Think of it as unwinding a stack.
请注意,该函数被标记为 async throws,但函数调用被标记为 try await – 正如我所说,关键字顺序是相反的。所以,它在函数定义中是 “asynchronous, throwing”,但在调用点是 “throwing, asynchronous”。可以将其视为展开堆栈。

Not only does try await read more easily than await try, but it’s also more reflective of what’s actually happening when our code executes: we’re waiting for some work to complete, and when it does complete we’ll check whether it ended up throwing an error or not.
try await 不仅比 await try 更容易读取,而且它也更能反映代码执行时实际发生的事情:我们正在等待一些工作完成,当它完成时,我们将检查它是否最终抛出错误。

Of course, the other possibility is that they could have try await at the call site and throws async on the function definition, and here’s what the Swift team says about that:
当然,另一种可能性是他们可以在调用站点try await 并在函数定义上throws async,以下是 Swift 团队对此的看法:

“This order restriction is arbitrary, but it’s not harmful, and it eliminates the potential for stylistic debates.”
“这种顺序限制是任意的,但无害,它消除了风格辩论的可能性。”

Personally, if I saw throws async I’d be more likely to write it as “this thing throws an async error” or similar, but as the quote above says ultimately the order is just arbitrary.
就个人而言,如果我看到 throws async,我更有可能将其写成 “this thing throws an async error” 或类似内容,但正如上面的引文所说,最终顺序只是任意的。

© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容