一个简单的承诺 异步代码很常见,但是如果我们仅在一个地方添加更多的异步调用,我们将得到大量的方法和十个级别的缩进。 换句话说,我们将成功实现回调地狱。 当然,我们可以做得更好! 我们可以尝试将其拆分为几个功能……但这可能会导致其他问题…… 这种方法的缺点是很难跟踪控制流。 从方法签名来看,不清楚哪个方法被调用。 如果方法调用是实现方法职责的一部分,那么这是一件好事,但是如果它调用了流程管道中的下一个项目,那么它很快就会变成可控流地狱。 这就是为什么我们首先要有回调! 我们希望在一个地方定义高级控制流,然后将实现细节放在其他地方,并适当地封装它们。 一种可能的解决方案是使用诺言。 那么, 什么是诺言? 承诺(也称为“未来”)是指用于同步程序执行的构造。 他们描述了一个对象,该对象充当最初未知的结果的代理 ,通常是因为其值的计算尚未完成[1]。 我为什么要使用诺言? 保持代码干净和结构良好。 这是避免回调地狱和控制流地狱之类的简单选择。 我们始终希望代码缩进尽可能合理 ,而诺言是实现这一目标的好方法。 答应过地狱? 根据使用方式的不同,promise可以简化代码,但也会使代码难以理解。 在进行代码审查时,我基本上遇到了一件奇妙的事情: 相当多的工作,不是吗? 乍一看,这是有问题的,因为代码在美学上看起来并不令人满意(在我看来,这是判断代码质量的很好指标)。 不幸的是,使用promise退化为类似代码的代码并不少见。 所以有什么问题? 很难说出.then块的作用,它们可能变得非常庞大。 它也违反了单一责任原则[2],因为每个块都有单独的责任,但是它们都包含在一个方法中。 我们遇到的另一个问题是缺乏抽象层的分离。 一个方法应该只包含占据一个抽象层的代码,在我们的例子中,我们可以说有两个:1.管理过程流程的代码,以及2.构成过程步骤的实现细节。 更好的承诺 一种简单的解决方案是在每个块的开头添加注释,以描述其功能。 更好的解决方案是编写自我记录代码 ,在这种情况下,这意味着将程序包提取到单独的方法中 。 只要确保正确命名方法即可 。 而且您还需要正确命名方法(我已经说了两次,因为它很重要,以防您想知道)。 最初的问题是,我们无法轻易分辨出发生了什么,而用模糊的内容代替它并不会带来太大帮助,对吗? 即使块的内容包含很多代码,如果将其包含在方法中,它也更易于管理,并且我们还解决了抽象层问题。 答应天堂? 由于Swift函数是一流的对象,因此我们可以采取进一步的措施。 这意味着我们可以将它们传递到其他需要关闭的函数中 。 promisseHell示例将变为以下内容: 我们可以选择几种承诺库。 最受欢迎的可能是PromiseKit [3]。 就我个人而言,我更喜欢then框架[4],因为它的方法不需要标签,这使它更加简洁(即在那时我们将编写.then (handler),而在PromiseKit中将是.then (execute:handler) )。 任一种都可以,但是您将需要根据所选框架的期望编写略有不同的代码。 […]
介绍 由于您已经阅读标题并查看了上面的图片,因此您想象会收到一些新闻。 一个新的框架? 一个新的第三方可以帮助您改善项目演示中的大量脏代码? 答案是肯定的,但根本不是。 承诺对您的帮助超出了您的预期。 因此,如果您是拥有高级商标的iOS开发人员,或者是技术领导团队,那么您可能会在意。 如果没有,请停止阅读更多内容并返回到滚动条。 您是否曾经在项目中使用异步任务? 说是? 好。 为此,举一个例子,当您想从Web服务(用于使用Youtube JSON api)获取视频列表时,您可能会知道: 使用Promise ,它看起来像: 给你惊喜吗 结果甚至令我惊讶。 什么? Promise是包装异步任务的对象。 传递该对象,并编写整洁,有序的代码; 从一个异步任务到另一个异步任务的逻辑,简单,模块化的流。 您现在所需要的就是:https://github.com/mxcl/PromiseKit 好消息: PromiseKit带有使UIAlertView , UIActionSheet , NSURLConnection , UIViewController , CLLocationManager等“ thenable”的类别。 例如,我们甚至试图变得超级方便。 将一个UIImagePickerController (等)实例传递给PromiseKit的 promiseViewController:animated:completion方法可自动处理幕后的常规委派,从而为您提供整洁,简单,受块支持的承诺。 这些都是使用PromiseKit的重要原因。 但是,诺言比那时更强大。 为什么? 它们使异步操作可链接和标准化。 他们清理异步意大利面; 它们简化了错误处理; 可以通知许多对象完成的信息,而不仅仅是一个。 和 它们使您的应用程序更强大。 与Promise合作时,我最钟爱的是什么? 它正在链接。 假设您要同时执行3个任务A,B和C,分别是先执行A,然后执行B,然后执行C。 可以,但更复杂且难以维护。 并承诺 流似乎正在穿过薄壁🙂 如何开始? Promise提供了一些您可以看到的关键字: […]
有了一个承诺,我就不需要在完成闭包中处理字典的解析,我可以将该动作链接到“获取JSON数据”动作。 见下文: 在上面的代码要点中,在第1行上,您可以看到我的getArticles()方法返回了Promise 。 此功能“有前途”的意思是,在我收到文章后,我将返回文章的承诺。 我将通过返回文章(也就是我在第13行的结果 )来实现这一承诺。 为了实现这些承诺,我使用了一个名为PromiseKit的第三方库。 我将向您介绍如何将PromiseKit集成到我的应用程序中。 首先 -为您的项目创建/打开一个Podfile。 在Terminal中,我使用Sublime(因此称为subl Podfile)打开了Podfile。 确保您位于项目文件的当前目录(文件夹)中。 第二个 -在您的Podfile中,在下面添加第10行。 保存并关闭此Podfile。 第三 —在终端中,键入“ pod install”。此说明将PromiseKit库安装到您的项目中。 第四 -在终端中,打开.xcworkspace (而不是.xcodeproj)! 第五步–在要编写网络代码的文件中,在顶部导入PromiseKit。 按⌘+ B,这会将PromiseKit库构建到您的项目中。 第六 -开始编写代码! 在这个应用程序示例中,我有一个Article模型(上文),它将从NYTimes API获取数据以创建Article对象。 我已经在上面的屏幕截图中注释了我的代码,但是我将在这里再次概述它: A —我没有使用完成闭包,而是让我的网络函数返回了类型为Promise的Promise。 B — Promise块需要实现和拒绝方法。 C-这个URL是我用来获取任何Cuba文章的NYTimes API数据的URL。 古巴是我去过的最有趣的国家。 (旁问:您访问过的最有趣的国家/地区是什么?) D-解开网址后,创建一个URLRequest E-创建一个URLSession F —创建一个URLDataPromise(PromiseKit随附)。 它返回一个专门的Promise包装URLSession.dataTask(with :)。 重要的是要注意,这是我们要做的第一个动作,第一个承诺。 我们正在写一个从dataPromise获取数据的承诺。 G —在我的dataPromise上,我做第二个PROMISE。 我们承诺将数据(从我们的第一个承诺开始)转换为反序列化字典。 您会注意到.then语法。 读起来很不错,就像您说的那样:“如果出现此内容,那么我会做些处理。” H-现在第二个承诺已经实现(我有一个字典),我可以使用该字典创建我的Article对象之一。 […]