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

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

在SWIFT 5.5中:

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

// Swift
func hi() async {
    print("hi")
}

func callAsyncHi() {
    hi()
}

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

// Javascript
async function hi() {
    console.log("hi")
}

function callAsyncHi() {
    hi()
}

callAsyncHi()

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

kadbb459

kadbb4591#

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

func hi() async {
    print("hi")
}

func callAsyncHi() {
    let task = Task {
        await hi()
    }
}

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

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

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

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

izkcnapc

izkcnapc2#

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

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

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

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

// swift compiler error: Expression is 'async' but is not marked with 'await'
func callAsyncHi() {
  Task {
    async let tmp = hi()
    print(Mirror(reflecting: tmp).subjectType)
    await tmp
  }
}

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

相关问题