SWIFT:无法从正常函数调用异步函数?

m1m5dgzv  于 2022-10-04  发布在  Swift
关注(0)|答案(2)|浏览(246)

在SWIFT 5.5中:

以下SWIFT代码将收到编译器错误:“在不支持并发的函数中进行异步调用”。

  1. // Swift
  2. func hi() async {
  3. print("hi")
  4. }
  5. func callAsyncHi() {
  6. hi()
  7. }

在Java脚本中,等待仅在异步函数中有效,但从正常函数调用异步函数是有效的。因此,跟随在Java代码后面的是异步打印的“hi”。

  1. // Javascript
  2. async function hi() {
  3. console.log("hi")
  4. }
  5. function callAsyncHi() {
  6. hi()
  7. }
  8. callAsyncHi()

我还发现,如果没有等待异步让,就无法调用异步函数。为什么SWIFT是这样设计的?

kadbb459

kadbb4591#

您可以通过将异步调用 Package 在任务中来从普通函数调用异步函数:

  1. func hi() async {
  2. print("hi")
  3. }
  4. func callAsyncHi() {
  5. let task = Task {
  6. await hi()
  7. }
  8. }

这类似于您可以从同步上下文调用Java脚本中的异步方法,关键区别在于在SWIFT中,您必须显式指定它,而在Task中,您可以调用多个异步方法。

这样的设计背后有一定的原因。关键原因是在SWIFT中,所有异步方法都与任务相关联,并支持cooperative cancellation
SWIFT并发性使用合作注销模式。每个任务在其执行过程中的适当时刻检查它是否已被取消,并以任何适当的方式响应取消。

通过要求async关键字,SWIFT跟踪异步调用的依赖链,并在发生取消事件时传播取消事件(而据我所知,JS中的承诺不支持取消承诺)。在上面的代码中,您可以通过跟踪task变量来调用取消。

现在,在我看来更重要的第二个原因是,通过要求显式调用,这使得审查代码变得更容易,因为我必须检查对这类调用的取消是否得到了适当的处理,而在JS的情况下,很难查明这种误用。

展开查看全部
izkcnapc

izkcnapc2#

  • 来自JAVASRIPT的异步函数返回Promise
  • C#的异步函数返回任务

我们自由地传递承诺/任务,做很多事情。

但SWIFT的异步函数返回**?**。

**?**是隐藏的。我甚至不能打印它的字体。

  1. // swift compiler error: Expression is 'async' but is not marked with 'await'
  2. func callAsyncHi() {
  3. Task {
  4. async let tmp = hi()
  5. print(Mirror(reflecting: tmp).subjectType)
  6. await tmp
  7. }
  8. }

我想没有**?。因此,我们必须使用带有等待**的异步函数。

展开查看全部

相关问题