如何巧妙使用 API 请求提高用户体验

如何巧妙使用 API 请求提高用户体验
原文标题:Crafting beautiful UX with API requests
原文链接:https://uxdesign.cc/crafting-beautiful-ux-with-api-requests-56e7dcc2f58e
作者:Ryan Baker


在构建 Web 应用时,首先要考虑的是如何创建一个优雅且响应迅速的 API 请求,让用户感受到舒适的交互体验。当我们在运行 Web 应用时,可能会出现一些意料之外的麻烦事情,比如开发人员没有考虑到处理 API 请求数据时会产生超时或者无法链接等情况。

在本文中,我将为你提供三种处理模式(包括代码片段),来帮助你的应用程序能弹性应对不可预测的情形。

模式 1:超时「超时」

是一种简单直接的处理模式。简而言之就是:“如果请求链接时间超出我的预期时间,请取消请求”。

什么时候用「超时」

你可以使用「超时」来设置你希望请求耗用的时长上限。如何知道你的 API 响应时间是否比预期的长?这取决于你的 API。

以下是一些现实场景的示例:你的服务器与数据库进行通信。数据库宕机了,但服务器的连接超时为 30 秒。服务器将花费完整的 30 秒来确定它无法与数据库通信。这意味着你的用户将等待 30 秒!

你可以使用了 AWS 负载均衡器,其背后的服务器已宕机(无论出于何种原因)。你将负载均衡器超时保留为默认值 60 秒,并且在失败之前一直尝试连接服务器。

什么时候不用「超时」

如果你的 API 已知响应时间具有可变性,则不应使用「超时」。一个很好的例子可能是返回报告数据的 API。请求一天的数据是快速的(可能是亚秒响应时间),但请求八个月的数据大约需要 12 秒。

因此,如果你无法确定对于请求应该花多长时间的可靠上限,则不要使用「超时」。

如何使用「超时」

假设你的应用程序中有一个方法可以做到这一点:

示例方法可能存在于 React 组件内部

你知道你的 API 在 99% 的时间里会在 3 秒内响应。假设你使用 Promises 从 API 获取数据,你可以这样做:

为你的 API 调用配置超时

注意:你可能用于进行 API 调用的大多数库都具有超时配置。请使用你工具的内置功能,而不是自己编写。

模式 2:最短等待时间

「最短等待时间」也是一种有效而简单的模式。它与「超时」相反:它可以保护你的应用免受 API 快速响应的影响。

什么时候用「最短等待时间」

如果要向用户显示加载状态,则「最短等待时间」是一种非常好的模式。因为 API 可能会快速响应,这带来的结果就是用户会看到加载状态,但是数据已经显示出来了,这显然不是一个良好的交互体验。

如果你显示加载状态,你是在告诉用户“稍等,系统正在处理中”。这让用户可以喘口气,也许查看一下他们的手机 —— 如果用户看到加载状态,那么用户希望等待。如果你获取太快,那就太突兀了。你打断了用户的预期状态,从而让他感到紧张。

什么时候不用「最短等待时间」

当你拥有响应速度始终非常快的 API 时,最好避免使用「最短等待时间」。不要为了添加加载状态而使用这种方式,如果不需要,就不要让用户等待。

如何使用「最短等待时间」

使用上面的示例,你可以编写“在这两件事完成之前不做任何事”的代码指令,如下所示:

强制请求的最短等待时间

模式 3:重试

「重试」模式是我将要介绍的最复杂的模式。意思是:如果得到错误的响应,我们想要重试几次请求。这是一个非常简单的方法,但在使用它时需要记住一些注意事项。

什么时候用「重试」

当你向可能发生间歇性故障的 API 发出请求时,很适合用这个方法。因为当你知道请求会经常因为无法控制的问题而导致失败时,几乎都希望进行「重试」。

就我而言,当我知道我正在发出使用特定数据库的请求时,我会经常使用这种方法。访问该数据库时,有时它会请求失败,而这是我们应该解决的问题。但是作为应用程序开发人员,当被告知需要“暂时先处理这个问题”时,我们可能没有能力修复底层基础架构问题。而这时候,我们就可以使用「重试」模式了。

什么时候不用「重试」

如果我们拥有可靠的且始终如一的响应式 API,则无需「重试」。如果响应失败并且重试后依然不能成功响应,那我们也就不需要重试了。大多数 API 都是比较稳定一致的。因此你需要谨慎使用这个模式。

如何使用「重试」

我们希望确保在发出请求时,不会对服务器造成冲击。假如因为负载过重造成服务器宕机,「重试」将会把一个已失去作用的服务器隐藏得更深。出于这个原因,我们在进行后续请求时需要所谓的退避策略。我们不希望在服务器宕机的情况下仍然立即一个接一个地发出 5 个请求。我们应该错开它们以减少 API 服务器上的负载。

大多数情况下,我们使用指数退避来确定在发送下一个请求之前我们应该等待多长时间。我们通常只想重试 3 次,所以这里有一个使用不同函数的等待时间示例:

我们立即发送第一个请求,它失败了。接下来,我们需要确定在发送第一次重试之前使用退避策略等待多长时间。让我们看一下这些曲线,其中 X 等于我们已经发送的重试次数。

然后,使用我们的二次(y = x²)函数和线性(y = x)函数,在第一个等待时间内我们得到 0,即应该立即发送下一个请求。

所以可以在运行时消除这两个函数了。使用指数(y = 2^x)函数和常数(y = 1)函数,我们得到 1 秒的等待时间。

常数函数使我们无法灵活处理已经发送的重试次数,从而改变我们应该等待的时间。

这就只剩下指数函数了。让我们编写一个函数,来告诉我们根据已经发送的重试次数确定等待多少秒:

简单的 y = 2^x 函数

在编写重试函数之前,我们想要一种方法来确定请求是否错误。假设状态码大于或等于 500 时,请求是错误的。我们可以为此编写下面这个函数了:

如果响应错误,我们的函数会抛出自定义错误

但你可能有不同的标准来确定请求是否失败。最后,我们可以使用指数退避策略编写重试函数:

我们使用指数退避策略重试

你会注意到我创建了一个我没有导出的函数(_retryWithBackoff)。使用我们的重试函数时,调用代码不能在迭代中显式传递。

总结

还有很多很好的防御模式可以给用户提供良好的交互体验。上文提到的三种 API 请求模式,你现在就可以用起来了。

订阅
qrcode

订阅

随时随地获取 Apifox 最新动态