继续上一节的话题,我们聊聊 async 对 closure 定义的影响。相比函数,这部分内容就少多了。还是继续之前 Dinner 的例子,我们给它添加一个自动煮饭的方法 cook

func cook(_ process: () async -> Void) async {
  await process()
}

然后,调用的时候,我们就可以这样:

await dinner.cook { () async -> Void in
  await dinner.chopVegetable()
  try? await dinner.marinateMeat()
  await dinner.preheatOven()
}

或者这样:

await dinner.cook {
  await dinner.chopVegetable()
  try? await dinner.marinateMeat()
  await dinner.preheatOven()
}

这个简单的例子,就几乎包含所有和异步 closure 用法有关的内容了。我们一个个来看下。

首先,我们用 () async -> Void 这种形式让 cook 接受一个异步 closure 作为参数。这和定义一个异步函数的形式是类似的。但要强调下的是,接受异步 closure 作为参数的函数自身,也必须是一个异步函数。这个很好理解,因为在 cook 实现的内部,我们肯定要调用 process,而异步函数只有在异步环境中才可以调用,因此 cook 必须是异步函数。

其次,当我们要显式定义一个 async closure 的时候,可以像这样:

{ () async -> Void in 
  // asynchronous closure
}

直接把 closure 的类型写在 {} 里。但这并不是必须的。就像第二个调用 cook 的例子,我们可以省略 closure 的类型,一旦 closure 里包含 await 语句,Swift 编译器就会自动把这个 clousre 标记为异步的。但要注意的是,这个推断只会自动应用到直接包含 await 语句的 closure,如果存在 closure 嵌套的话,其它外层的 closure 仍旧是同步的。

What's next?

实际上,cook 的调用还有第三种方法,像这样:

func myCook() async {
  print("My own cooking approach.")
}

await dinner.cook(myCook)

但为什么我们刚才没有提到呢?其实,说到现在,我们一直都在有意弱化和 await 相关的内容,在不影响理解的情况下,我们只是把它当成了一个可以跑通程序必须要使用的工具而已。在下段视频里,我们就正式和大家介绍 await 的用法以及和 await 有关的一个概念:suspension point。

所有订阅均支持 12 期免息分期

¥ 59

按月订阅

一个月,观看并下载所有视频内容。初来泊学,这可能是个最好的开始。

开始订阅

¥ 512

按年订阅

一年的时间,让我们一起疯狂地狩猎知识吧。比按月订阅优惠 28%

开始订阅

¥ 1280

泊学终身会员

永久观看和下载所有泊学网站视频,并赠送 100 元商店优惠券。

我要加入
如需帮助,欢迎通过以下方式联系我们