王磊磊
作者王磊磊·2017-08-30 13:59
系统工程师·移动

如何处理变慢的API

字数 2280阅读 1139评论 0赞 2

译者注:作者对造成API缓慢的原因进行分析,介绍处理API缓慢的两种方法,一在公共共享服务中维护一个标志,二是停止处理缓慢API的响应,最后总结处理缓慢API的注意点。

在开始时表现良好的API会随着时间的推移而导致性能降低。学习如何管理和解决这些性能问题是开发者必须具备的技能之一。

作为一名工程师,你花了很多时间在API上——你要么是为别人构建API,要么是在使用别人的API。使用API既是一门艺术,也是一门科学。工程师们犯的最常见的错误之一就是对性能的思考不够充分。我们希望让事情先做起来,然后再处理性能问题。这很好,但是如果在构建v1的时候能够意识到这一点,你以后就可以避免。如果你使用API的时间够长,我相信你知道刚开始一切都很顺利,但随着时间的推移,API就会变得缓慢。

当我们在使用别人API时,这些API是我们几乎无法控制的,那就会变得很棘手。通常,许多API在最初的几毫秒内就会响应,但随着时间的推移,复杂性的增加,它们开始变得缓慢。一些用户操作可能会在我们正在使用的API中触发一个代价高昂的查询,然后就会出现问题。API不能保证预期性能,所以在使用API时,意识到这点会督促您关注什么样的东西会减慢它们的速度,尤其是在项目的关键路径上。

我们来看一个或两个用户操作共享一个视图区域以显示其响应的用例。如果其中一个连接到这些操作的API需要花很长时间,那么我们可能会遇到,如果处理不当视图就会混乱的情况。

例如Google’amzn股票’,您会看到如下所示:由用户选择的时间范围控制的一个单一的股票趋势图,如1天、5天、1个月等。

20170829090843680.png

20170829090843680.png

当我们切换时间段时,视图区域会反映变化。让我们假设您的API调用获取1年趋势图会出现问题,用户点击它,它一直在加载,那么用户失去耐心,切换到一个较短的时间段,比如3个月,则立刻加载出图表。当用户正在查看3个月的图表时,刚开始获取1年数据的API调用返回其响应并重新绘制具有1年数据的图表。

这不是一个复杂的问题。你可以查看当前活跃的时间段,忽略晚到的响应。但是,当您构建v1时,您可能不认为在开发UI时需要这种处理,因为当您开发它时,所有的API都会立即返回。您可能没有预料到API会在某些场景中或随着时间的推移而减慢。

现在,如果这种情况影响到应用程序中提供多个组件的公共共享服务的状态,情况可能会变得更糟,并且在这种情况下寻找根本原因会变得非常复杂。

我们来看看如何解决这个问题。一个简单的方法是在该公共共享服务中维护一个标记,以跟踪我们当前期待响应的后台API。但是如果我们多次调用同一个API会怎么样呢?标志是行不通的。我们可以延长标志来存储每个后台API调用的“状态”,但这会变得混乱和复杂,每当我们去存储状态,我们都要承担很大的风险,因为“记住”API的变化,我们需要保持状态更新,但这几乎总会导致不良的缺陷。

所以你维护的“全局”状态越少越好。它不仅有助于保持代码简单和模块化,而且还为您提供更多自由去提高并发性。

在这种情况下,一种更好的方法是,不要处理来自慢速API的响应,而是简单地停止接收来自它的响应。只需终止那些您不再关心响应和继续运行的API。您可以通过跟踪所有正在进行的API调用来轻松地执行此操作,并且当您需要启动新的API调用时,只需终止不再需要的先前的调用即可。

如果您使用的是jQuery ajax方法,那么请保留对jQuery ajax方法返回的XMLHttpRequest的引用,并在适当的时候调用您的流中的中止方法。

如果您使用的是ES6 promises,那么对不起,这是行不通的——您不能终止与promises相关的一个正在进行的API调用。更多关于promises使用在这里。

欢迎来到RxJS世界!RxJS试图通过完全异步的事件驱动模型来为API性能的混乱带来秩序。如果某件事需要时间,那就花点时间吧。让我们用我们所拥有的一切来运行。我不是在这里讨论它是好是坏,或者它是否是最好的方法,但是我发现用RxJS处理这些类型的情况是很方便的。

在这种情况下,您可以简单地在您的可观察对象上使用一个switch 结构,并获得您感兴趣的最新异步事件,而不必担心任何状态维护或终止先前正在进行的API。当您使用正确的构造时,这个库内部为您做了所有这些操作,所以您不必担心它们!

以plunker为例。

在这个例子中,一个缓慢的API使用Observable.timer。 作为共享服务构造函数的一部分创建的RxJS主体实例asyncActionSubject,使用switch结构来简单地切换到返回的最新observable。 其余的都由RxJS框架负责。在这里查看RxJSGitHub页面了解更多详细信息。

关键小贴士

在使用API时,请始终考虑什么情况可能导致其减慢。您可以根据API正在做什么,返回多少和什么类型的数据,以及如果您正在测试的简单例子变得复杂时将会发生什么。如果你的代码路径结合许多过滤器和选择器为用户操作服务,那么这一点尤为重要。

始终考虑大局–用户如何与您的代码交互,进而影响你正在使用的API?退一步,思考会出什么错,从源头处理这些情况。

总是尽可能分散和无状态。集中和有状态是调试和并发性的敌人。这可以节省很多麻烦。

小心使用异步调用——它们是好的,但它们也会很棘手。了解它们在您的情况下如何工作,以及当调用按时间顺序返回时会发生什么。

最后,越少越好。即使一个API返回很多数据量,最低数据量和实际上消耗的最少数据量。

作者:Tom Smith

如果觉得我的文章对您有用,请点赞。您的支持将鼓励我继续创作!

2

添加新评论0 条评论

Ctrl+Enter 发表

作者其他文章

相关文章

相关问题

X社区推广