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

最近,我们在标准银行工程部遇到了一个问题,即我们同时运行相同的服务调用。 在任何给定时间都有大量用户使用该应用程序的情况下,任何昂贵且不必要的服务调用都可能给您的后端系统带来巨大压力,并给应用程序以缓慢的感觉。

与往常一样,您可以遵循以下提供的游乐场文件:

TYRONEMICHAEL /缓存的承诺
缓存的承诺–使用Promise类型 github.com 解决歧义并提高性能

描述最初的问题

我们有许多不同的功能团队。 如果我们需要特定团队的数据或功能,则该团队可提供面向公众的界面。 使用该接口的其他功能团队不在乎实现。 让我们看一个简单的例子。

这将是面向公众的界面的示例。

现在应该缓存所有服务调用,因此让我们编写一个用于缓存用户的快速接口和实现。

最后是实现公共接口的存储库的私有实现。

让我们退后一步,更详细地说明上述内容。

  • 该实现检查缓存以查看我们是否有当前用户,如果找到用户,则返回该用户。
  • 如果找不到用户,我们将触发服务调用以获取用户。 我们在后台线程上进行所有服务调用,从而防止任何人锁定主线程。 如果在主线程上完成了服务调用,则会引发致命的运行时错误。
  • 提取用户后,我们将填充缓存。

您可以使用以下代码段测试上述内容。

现在,这种方法存在三个主要问题:

  • 无法确定服务呼叫是否已触发并且尚未返回。 因此,我们可以在填充缓存之前发生多个服务调用。
  • 如果我们看一下接口,我们不知道我们必须在后台线程上运行该函数。 是的,该应用程序将在运行时引发致命错误,但我们也不必查看实现。
  • 最后,我们可能会意外地在主线程上调用getCurrentUser()而不是崩溃,因为缓存已被填充。

这是我们需要解决的三个重要问题。

使用Promise解决问题

在开始解决方案之前,重要的是要提及结果类型。 我在我的很多文章中都提到了它,但是基本上一个应用可以处于两种状态之一,即成功状态失败状态 。 维基百科很好地总结了它。

结果类型提供了一种优雅的错误处理方式,而无需求助于异常处理。 当可能失败的函数返回结果类型时,程序员必须在获得预期结果之前考虑成功或失败的路径; 这消除了错误的程序员假设的可能性。

现在,程序可以进入另一个状态。这就是Promise Type的出现。Wikipedia再次很好地总结了Futures和Promises。

Promise and Futures描述一个对象,该对象充当最初未知的结果的代理,通常是因为其值的计算尚未完成。

基本上,您可以将Promise视为未来的结果 。 因此,更正我之前的陈述,程序实际上可以处于以下三种状态之一:

  • 成功状态
  • 失败状态
  • 等待/未知状态

有很多框架和库影响了Promise或Future Type,但我专门使用Google的框架和库。 通过更新我们的界面:

至:

我们消除了所有歧义。 我们不再需要查看实现以确定是否必须在后台线程上运行该函数。 我们承诺 最终将获得价值。 合同明确规定:在我们尝试满足您的要求的同时,做您需要做的事情。 如果我们无法满足您的要求,我们将告知您原因,以便您可以进行相应处理。 否则,您的结果将在将来的某个时候到达。

重构我们以前的实现

我们可以更新实现,以使当前用户关注以下内容。

但是我们仍然需要缓存我们的结果。

但是,除了缓存我们的结果,我们不能简单地缓存Promise吗? 通过以下内容更新我们的缓存协议和实现。

现在,我们可以更新存储库以缓存Promise,并防止在不花哨或复杂的情况下触发不必要的服务调用。

最后,如果Promise失败,我们将捕获并清除缓存。

我建立了一个小操场,以视觉方式说明我们所取得的成就。 我们有两个选项卡,彼此独立,需要相同的数据集。 两个选项卡都使用相同的界面来同时调用相同的功能。

如果服务呼叫失败,我们将获得以下信息。

使用以下Playground文件使用所有代码测试以上内容:

TYRONEMICHAEL /缓存的承诺
缓存的承诺–使用Promise类型 github.com 解决歧义并提高性能

无极是一个函子和一个单子

Google有一个出色的Swift Promise框架,可与Swift和Objective C兼容。它与我在Playground示例中使用的库相同。 因此,如果您愿意使用flatmap并使用Arrays,Optionals和/或Result Type进行map ,您将很高兴知道Promise Type遵循相同的定律,可以像以前一样构造函数。 不过,让我们下次再讨论更多。

在Twitter上关注我,我经常喜欢在这里发布诸如此类的有趣话题。

泰隆·阿芙妮(@tyroneavnit)| 推特
Tyrone Avnit(@tyroneavnit)的最新推文。 爸爸,丈夫和多语言程序员。 专门从事iOS… twitter.com