在Swift中从回调到异步/等待

自从我写了一篇博客文章已经有一段时间了(实际上,这是我的第一篇文章,我没有任何借口!),但是我真的很想接触Swift中的异步编程。 您在Swift中编写的大多数代码至少必须在某种程度上考虑异步性。 在经过一些通常不属于控制器层的计算后更新ui时,即使如此,您也必须考虑这段代码的正确位置。

在除主线程之外的其他线程上更新UI是一个常见错误,可能会导致错过UI更新,视觉缺陷,数据损坏和崩溃。

当初学者从iOS开始时,他们会在其他进程完成后使用回调执行某些功能。 通常,如果需要,在操作完成后执行的功能链的最后一部分将是更新UI。 假设是这种情况,使用回调我们将必须在整个回调链中反复传递“ Update the UI”回调,直到到达链的末尾,最后调用该回调来更新UI,假设我们不想通过调用UI来污染我们的域/基础架构逻辑,因为我们重视关注分离。

让我们看一下一段代码如何从简单的回调演变为使用异步/等待,从而使您可以在后台线程中编写完全阻塞的代码,而每次只需编写几行额外的样板代码。 这与我刚开始使用Swift时编写的混乱非常接近。

我们的用例:我们正在构建一个应用程序,该应用程序将首先发出HTTP请求以检索一些json。 此json中是我们要下载的图像的URL。 最后,下载完该图像后,我们应该将其呈现给用户并在UI中显示。 让我们首先使用回调来构建它。

第一步是使用Data(contentsOf:)下载一些json,该json只是向端点执行GET请求,而没有任何标头或其他信息。 实际上,这是执行下载的最差方法。 Data(contentsOf:)应该仅用于本地文件,但是出于本博客文章的目的,假定绝对没有故意进行错误检查。

Grand Central Dispatch,简称GCD,提供了一个简单而强大的API,通过它我们可以在单独的线程中执行“后台”操作。

首先,让我们创建一个接受String并返回UIImage闭包。 然后,我们可以将其传递给对JsonDownloader的调用。

首先让我们看一下入口点,即ViewController 。 为了使这项工作涉及承诺,我们还需要做其他事情,但是目前,这是顶层代码。

我已经使用PromiseKit和AwaitKit已有几个月了,从编写带有回调的异步代码到此方法的变化令人震惊-它们使我的开发变得更加轻松和有趣!

我希望这篇文章能说服一些人看一下async / await,并将其从回调地狱更改为看起来更简洁易用的东西。

在下面的评论中让我知道,如果您当前的代码库中有回调地狱,是否正在考虑将其检查出来,或者是否有其他替代方法在更复杂的代码库中也能正常工作!


最初于 2018 年8月8日 发布在 blog.j7mbo.com 上。