Tag: Promises

使用Promise类型解决歧义并提高性能

最近,我们在标准银行工程部遇到了一个问题,即我们同时运行相同的服务调用。 在任何给定时间都有大量用户使用该应用程序的情况下,任何昂贵且不必要的服务调用都可能给您的后端系统带来巨大压力,并给应用程序以缓慢的感觉。 与往常一样,您可以遵循以下提供的游乐场文件: TYRONEMICHAEL /缓存的承诺 缓存的承诺–使用Promise类型 github.com 解决歧义并提高性能 描述最初的问题 我们有许多不同的功能团队。 如果我们需要特定团队的数据或功能,则该团队可提供面向公众的界面。 使用该接口的其他功能团队不在乎实现。 让我们看一个简单的例子。 这将是面向公众的界面的示例。 现在应该缓存所有服务调用,因此让我们编写一个用于缓存用户的快速接口和实现。 最后是实现公共接口的存储库的私有实现。 让我们退后一步,更详细地说明上述内容。 该实现检查缓存以查看我们是否有当前用户,如果找到用户,则返回该用户。 如果找不到用户,我们将触发服务调用以获取用户。 我们在后台线程上进行所有服务调用,从而防止任何人锁定主线程。 如果在主线程上完成了服务调用,则会引发致命的运行时错误。 提取用户后,我们将填充缓存。 您可以使用以下代码段测试上述内容。 现在,这种方法存在三个主要问题: 无法确定服务呼叫是否已触发并且尚未返回。 因此,我们可以在填充缓存之前发生多个服务调用。 如果我们看一下接口,我们不知道我们必须在后台线程上运行该函数。 是的,该应用程序将在运行时引发致命错误,但我们也不必查看实现。 最后,我们可能会意外地在主线程上调用getCurrentUser()而不是崩溃,因为缓存已被填充。 这是我们需要解决的三个重要问题。 使用Promise解决问题 在开始解决方案之前,重要的是要提及结果类型。 我在我的很多文章中都提到了它,但是基本上一个应用可以处于两种状态之一,即成功状态或失败状态 。 维基百科很好地总结了它。 结果类型提供了一种优雅的错误处理方式,而无需求助于异常处理。 当可能失败的函数返回结果类型时,程序员必须在获得预期结果之前考虑成功或失败的路径; 这消除了错误的程序员假设的可能性。 现在,程序可以进入另一个状态。这就是Promise Type的出现。Wikipedia再次很好地总结了Futures和Promises。 Promise and Futures描述一个对象,该对象充当最初未知的结果的代理,通常是因为其值的计算尚未完成。 基本上,您可以将Promise视为未来的结果 。 因此,更正我之前的陈述,程序实际上可以处于以下三种状态之一: 成功状态 失败状态 等待/未知状态 有很多框架和库影响了Promise或Future Type,但我专门使用Google的框架和库。 通过更新我们的界面: 至: 我们消除了所有歧义。 我们不再需要查看实现以确定是否必须在后台线程上运行该函数。 […]

从webView到JavaScript的回调:在本机代码和html之间共享数据

eDetailing(以及其他使用html5显示内容的应用程序)是一个非常普遍的技术问题,您需要在本机iOS(或Android,Windows)代码和html演示文稿之间共享数据。 而且代码可以而且确实会变得凌乱。 当您尝试在UIWebView和JavaScript库之间共享数据时,最终将得到类似的结果。 这样做的问题很明显:您定义了业务逻辑,然后调用iOS方法,应用程序有时会调用其他方法作为回调。 您最终将状态存储在全球范围内,并试图猜测当前您在过程中的确切位置。 幸运的是,最近在JavaScript中出现了一些警告,这些问题都消失了: 承诺 可观察的 发电机功能 我们的目标是消除工作流中的发送方和回调之间的中断,并能够专注于业务逻辑,而不必担心在何处以及如何接收数据: 我只希望在调用本机函数时返回Promise 。 接回电话 首先,我们需要解决中断问题并在不离开发送方的情况下捕获回调。 为此,我们可以使用Observer模式 ,即ReactiveX。 我们观察何时调用回调: 回报承诺 现在,我们可以将所有这些内容简单地包装在Promise中,并在订阅者收到数据时对其进行解析 。 我还添加了一个超时,因此如果iOS代码出错,该代码将不会挂起。 另外,我们使用Bluebird,因为它比本地Promise快得多。 清洁业务逻辑代码 现在回到业务逻辑。 多亏了Promise, 我不必离开业务逻辑功能的范围 。 使用co(或简单的生成器函数)将有助于使代码更加清晰。 而且由于要调用的函数集有限,因此可以为与本机iOS代码进行的所有交互创建一个漂亮的,抽象的和通用的库。 这里有一个完整的例子。

使用PromiseKit在Swift中承诺

Promise在Java Script中非常强大,可帮助我们处理异步编程过程。 现在我们可以通过PromiseKit在Swift中使用Promise mxcl / PromiseKit PromiseKit – Swift和ObjC的承诺 github.com 例如,我们有一个任务要做,即从后端获取图片网址,然后从该网址下载图片,最后在图片视图上显示图片 所以对于正常的工作,我们会这样做 它只是一个简单的获取URL和下载图像,但我们仅出于一个目的就需要完成三个任务:(1)获取Image Url,等待获取完成,然后下载图像(2)最后在下载时在ImageView中显示该图像过程已经完成。 因此,让我们通过Promise使这项工作更加容易,让我们在此文章顶部的Git Hub链接中安装Promise。 首先,我们创建“获取网址的承诺”并下载图片 现在将这些Promises连接在一起,我们可以将其称为Promise Chain,下一个.then()将以先前的返回值作为参数 好的! 现在更容易。 在过程中,让我们进入显示/隐藏指示器的下一个级别 因此,有一段时间我们遇到了一个问题,我们需要处理多个异步任务,然后等待那些结果继续并且这些结果不是相同的格式。 好吧,这可能会使您的应用程序变慢。 幸运的是,我们在PromiseKit中有“ when()”。 在when()中,添加要同时执行的所有promise,它将等待所有promise解析后再继续。 让我们来看看 PromiseKit可以做很多事情,在我的文章中只关注并发。 Promise提高了可读性,并使控制并发变得更加容易。 有关PromiseKit的更多信息,让我们尝试一下PromiseKit文档:https://github.com/mxcl/PromiseKit/blob/master/Documentation/CommonPatterns.md

使用Promise模式在Swift中编写更干净的异步代码

在Swift 4中编写异步代码的当前状态是什么? 当前最常用的模式是提供一个回调闭合,当任务完成传递结果或错误时将调用该闭合。 尽管此模式有效,但是当我们需要编写多个异步任务时(这也取决于先前任务的结果),很难维护和理解它。 异步函数相互嵌套在一起,在我们的代码中可能会导致“厄运金字塔”。 计算机科学家发现的解决此类问题的方法之一是使用Promise模式,该模式被广泛用于编写现代ES6 Javascript应用程序。 什么是承诺? 简而言之,promise是一个对象,代表异步任务的最终完成(或失败)。 操作的完成状态可以为未决,失败和完成: 待处理:任务尚未解决,任务尚未完成。 已完成:具有价值结果的已解决任务 拒绝:已解决任务,但有错误。 许诺对象完成或失败时的状态是最终状态,永远不会改变。 许诺对象可以附加到许多观察者,当许诺完成其任务(提供值的结果)或当许诺失败(使用错误对象提供错误原因)时,可以通知这些观察者。 完成后,promise的观察者将返回另一个promise对象,或者他们可以返回void以结束订阅。 当它返回另一个promise对象时,它可以用于执行异步任务转换的多个链接管道,以转换每个promise的值。 Promises的其他主要功能: 并行执行多个异步任务,并在所有任务成功完成时解决。 执行许多异步任务的竞赛,并使用其值解决首先完成的任务。 对promise的错误处理也非常简单,只有一个简单的catch错误处理程序可以捕获所有promise管道操作。 查看上面的源代码,我们可以看到,使用Promise链接模式和单个错误捕获处理(如果任何promise失败),可使代码看起来更简单易维护。 我们可以使用许多Cocoapods库将Promise集成到我们的iOS应用程序中。 我最喜欢的之一是Google编写的Promises库,它是用Objective-C编写的,并且与Swift完全兼容。 与其他PromiseKit等Promise库相比,该库的性能也相对较快,并且二进制大小更轻巧。 只需将此行添加到您的Podfile中即可进行集成: pod’PromisesSwift’ Google Promises库的主要功能取自其GitHub存储库: 简单:该框架具有直观的API,这些API的文档齐全,可轻松集成到新代码或现有代码中。 互操作性:支持Objective-C和Swift。 在Objective-C中创建的承诺可以在Swift中使用,反之亦然。 轻量级:具有最小的开销,可以达到与GCD和完成处理程序类似的性能。 灵活:可以在任何线程或自定义队列上调度观察者块。 安全:GCD捕获了所有的诺言和观察者阻止,这有助于避免潜在的保留周期。 已测试:该框架具有100%的测试覆盖率。 谷歌/承诺 Promises是一个现代框架,为Swift和Objective-C提供了同步结构。 – google / promises github.com 我们创建一个接受ClosedRange Int作为参数的函数,然后输出一个Promise对象,该对象通过执行参数中传递的数字范围的总和来解析为整数值。 要创建Promise对象,我们只需使用Promise初始化程序,它是一个通用的初始化程序。 我们使用Int作为返回值,然后告诉初始化程序在全局调度后台队列内执行执行。 我们将一个闭包传递给包含要执行的任务的初始化程序,该闭包提供2个参数,complement和reject。 我们使用实现来解决带有值的承诺,而使用拒绝来解决带有错误的承诺。 我们调用传递范围在1到100之间(包括1和100)的数字范围的函数,以生成Promise对象,我们可以通过使用then关键字来传递观察值,该关键字传递在promise解析结果以打印结果时将调用的闭包。 如果您要链接另一个Promise,也可以在完成闭包中返回另一个Promise对象,在这种情况下,由于我们不返回任何Promise对象,因此Promise链已结束。 在这里,我们创建一个返回Promise的函数,在promise任务闭包内,我们只是拒绝传递生成的NSError对象的任务。 我们调用该函数以生成Promise,然后对其进行观察。 底部的catch关键字将始终捕获Promise链中的错误。 在此示例中,我们将创建2个Promise: […]

在Swift中同步多个异步任务

您可能会遇到这样的情况:首先需要完成一些异步任务,然后才能跳到快速程序的下一个阶段。 在本文中,我们研究了可以应用于异步运行任务并在流程结束时获得通知或获取结果的不同解决方案。 通常,您可能需要先存储多个网络请求的结果,然后再向用户显示正确的数据。 的确,如果您必须请求许多网络资源来执行应用程序的功能,它可能会消耗更多的设备能量,您可能会三思而后行,但这与本文无关。 假设我们有一个示例网络请求函数,如下所示: 我们希望通过网络满足一些网络要求: 在上面的示例中, baseUrl指示我们的基本端点URL,并且这些endpoints是来自Web服务器的不同请求。 多个独立任务(并发队列) 我们可以有彼此独立的不同异步任务。 这意味着我们可以以任何顺序运行它们,并且一个结果与另一任务无关。 派遣组 Grand Central Dispatch或GCD自动管理线程的创建,并根据iOS中可用的设备资源来平衡线程的创建。 我们可以使用DispatchGroup创建一堆异步任务,并在所有任务完成后继续我们的工作: 当任务完成时,我们已通知主线程,但也可以是其他任何线程。 以下输出可能是结果(或子任务完成的任何任意顺序): 任务相册已完成 任务发布完成 待办事项 任务注释已完成 任务用户完成 任务照片完成 所有任务都完成了 如您所见,在处理完所有任务后,我们收到了“所有任务已完成”消息。 承诺 强烈建议您使用一种模式来解决此问题:承诺。 一般来说,promise表示异步任务的最终结果 ,或者表示任务失败时的错误原因 。 类似的概念也称为期货 (有关更多信息,期货和承诺,请参阅此Wiki文章)。 我们可以假设一个承诺的3个不同状态: 待处理 :尚未解决的任务,结果尚不可用 已完成 :具有一定价值的已解决任务(成功响应) 拒绝 :已解决任务,但有错误 有很多Cocoapods库可以提供承诺。 Google Promises是Swift中最好的实现之一: 谷歌/承诺 Promises是一个现代框架,为Swift和Objective-C提供了同步结构。 – google / promises github.com 现在我们可以使用Promises更新解决方案: 可以看出,promise简化了异步任务过程。 在performNetworkPromise我们首先创建了一个待处理流程,该流程将返回一些数据。 就像我们已初始化的一个空的异步请求容器一样。 承诺中的数据类型决定了将要满足的数据类型。 […]

101:Alamofire和PromiseKit

使用Alamofire执行异步请求时。 您的代码看起来像这样吗? 好吧,那很好,但是可以更好。 怎么样? 承诺! 承诺 Promise简化了异步编程,您可以在其中基于事件编写代码。 这样可以使您的代码更简洁,可读性更好。 它还将帮助您减少特别是在处理异步请求时以很多委托或复杂的完成处理程序结尾的可能性。 在本文中,我将使用PromiseKit这个建议中使用的流行Swift库。 许诺是代表异步任务的对象。 传递该对象,并编写整洁,有序的代码; 从一个异步任务到另一个异步任务的逻辑,简单,模块化的流。 资料来源:http://promisekit.org/docs/ 一个Promise有一个then块,就像一个onSuccess完成处理程序。 它还有一个catch块,将错误处理与您的主代码路径分开,就像onFailure完成处理程序一样。 我们将在开始时使用相同的示例将请求与承诺包装在一起,它看起来像这样: 使用基于PromiseKit版本的代码示例 现在您可以像这样使用它: 如您所见,不需要定义委托或完成处理程序,我们利用PromiseKit的then块和catch块分别处理有效响应和错误。 注意:在最新的PromiseKit版本中, then被分为then , done和map 。 有关更多信息,请查看PromiseKit 6发行说明。 我知道Promise真是太棒了!但是,在您开始采用PromiseKit之前,我强烈建议您慢慢使用它,并在其“入门指南”或他们的网页中阅读有关此库的更多信息。 然后,当您感到舒适时,才开始用promise打包所有异步请求。 愿原力与你同在… (我最近看过《星球大战:最后的绝地武士》,我被炒作了……让我成为吧) 我希望您喜欢这篇文章,并且总体上觉得它很有用。 并且不要犹豫,留下反馈或任何问题。 谢谢!

无极内部

我如何在Swift中构建Promise / A +库 Hydra的GitHub页面 上也提供了这篇文章 介绍 在Objective-C中进行异步编程从来都不是真正令人兴奋的经历。 我们已经使用了多年的代表(我仍然记得我第一次见到它,那是在2001年左右,当时我在Mac OS X上玩过Cocoa的乐趣) ,不久前我们也参加了完成会议处理程序。 但是,这两个过程都不能很好地扩展,并且不能提供可靠的错误处理机制 ,特别是由于语言本身的某些限制( 是的,您几乎可以在C语言中执行任何操作,但这不在本文的讨论范围之内 )。 在厄运的回调金字塔(也称为回调地狱)中迷失自己是很容易的,并且通常您的代码最终变得不那么优雅,阅读和维护起来也不那么简单。 Promises可以帮助我们编写更好的代码,并且在诸如await/async之类的结构的帮助下,处理异步编程确实是一种乐趣。 早在2016年11月,我就决定在Promise库中工作,只是为了进一步了解如何实现此概念以及如何使用Swift这样的现代语言来实现这一概念。 在本文中,我将更深入地了解Promise库:Hydra的体系结构。 在本文中,您不会了解如何在下一个杀手级应用程序中使用Hydra,但将了解它在幕后的工作方式(但是我为Hydra编写了完整的文档,可在GitHub上找到它)。 什么是诺言? 承诺是将来可能会产生单一价值的对象。 该值可以是您期望的对象(即JSON响应)或失败原因(即网络错误) 。 许诺可能处于以下状态之一:已resolved (或已fulfilled ),已rejected或pending 。 一个承诺开始于待处理状态,可以转换到两个状态中的另一个状态。 一旦解决,就无法重新安置。 Promise的用户可以附加回调(或观察者)以获取有关任何状态更改的通知。 then ,Promise的最常见的运算符是and catch ,用于获取Promise的值或捕获任何发生的错误。 但是,还有其他几个运算符可以大大简化网络代码的编写方式,但我们稍后会介绍。 一点历史 Promise的历史可以追溯到很久以前,即1980年代初。 最早的实现最早是在1980年代以Prolog和Lisp等语言出现的。 “ Promise ”一词由Barbara Liskov和Liuba Shrira在一篇名为“ Promises:分布式系统中对高效异步过程调用的语言支持”的学术论文中提出(1988)。 随着承诺兴趣的增长,ECMAScript标准重新定义了Promise的新规范:Promise / A +用于定义Promise的边界和行为。 符合Promise / A +实施的主要规则是: Promise或“ […]