[譯] 用 API 請求製作賞心悅目的 UX

MeFelixWang發表於2018-09-12

在構建 Web 應用時,首先要建立一個優雅且響應迅速的體驗。

試圖控制超出 Web 應用程式範圍的體驗通常是事後的想法。工程師忘記了處理從 API 請求資料時可能會遇到的所有麻煩事情。在本文中,我將為你提供三種模式(包括程式碼片段),以使你的應用程式能彈性應對不可預測的情形。

[譯] 用 API 請求製作賞心悅目的 UX

讓你的使用者和這個愚蠢的人類一樣快樂

模式 1:超時

超時是一種簡單的模式。簡而言之,就是:“如果你的反應比我想要的慢,請取消我的請求”。

什麼時候用

你應該使用超時來設定你希望請求耗用的時長上限。有什麼可能會使你的 API 響應時間比預期的長?這取決於你的 API,但以下是一些現實場景的示例:

你的伺服器與資料庫進行通訊。資料庫當機了,但伺服器的連線超時為 30 秒。伺服器將花費完整的 30 秒來確定它無法與資料庫通訊。這意味著你的使用者將等待 30 秒!

你使用了 AWS 負載均衡器,其背後的伺服器已當機(無論出於何種原因)。你將負載均衡器超時保留為預設值 60 秒,並且在失敗之前一直嘗試連線伺服器。

什麼時候不用

如果你的 API 已知響應時間具有可變性,則不應使用超時。一個很好的例子可能是返回報告資料的 API。請求一天的資料是快速的(可能是亞秒響應時間),但請求八個月的資料大約需要 12 秒。

如果你無法確定對於請求應該花多長時間的可靠上限,則不要使用超時。

如何使用

假設你的應用程式中有一個方法可以做到這一點:

[譯] 用 API 請求製作賞心悅目的 UX

示例方法可能存在於 React 元件內部

你知道你的 API 在 99% 的時間裡會在 3 秒內響應。假設你使用 Promises 從 API 獲取資料,你可以這樣做:

[譯] 用 API 請求製作賞心悅目的 UX

為你的 API 呼叫配置超時

注意:你可能用於進行 API 呼叫的大多數庫都具有超時配置。請使用你工具的內建功能,而不是自己編寫

模式 2:最短等待時間

最短等待時間也是一種簡單的模式。它與超時相反:它可以保護你的應用免受 API 快速響應的影響。

什麼時候用

如果要向使用者顯示載入狀態,則最短等待時間是一種非常好的模式,但 API 可能會快速響應。結果就是使用者會看到載入狀態,接著資料“彈出”進入檢視,然後其才能專注於想做的事。

這不是一個良好的體驗。如果你顯示載入狀態,你是在告訴使用者“稍等,我們正在處理些事兒,我們會馬上回來”。這讓使用者可以喘口氣,也許檢視一下他們的手機 —— 如果使用者看到載入狀態,那麼使用者希望等待。如果你獲取太快,那就太突兀了。你打斷了她的休息,讓她變得緊張。

什麼時候不用

當你擁有響應速度始終非常快的 API 時,最好避免使用最短等待模式。不要為了新增載入狀態而新增,如果不需要,就不要讓使用者等待。

如何使用

使用上面的示例,你可以編寫程式碼“在這兩件事完成之前不做任何事”,如下所示:

[譯] 用 API 請求製作賞心悅目的 UX

強制請求的最短等待時間

模式 3:重試

重試模式是我將要介紹的最複雜的模式。基本的想法是,如果得到錯誤的響應,我們想要重試幾次請求。這是一個非常簡單的想法,但在使用它時需要記住一些注意事項。

什麼時候用

當你向可能發生間歇性故障的 API 發出請求時,你會希望使用此方法。當知道請求會不時因為無法控制的問題而失敗時我們幾乎都希望重試。

就我而言,當我知道我正在發出使用特定資料庫的請求時,我會經常使用它。訪問該資料庫時,有時它會失敗。是的,這很糟糕。是的,這是我們應該解決的問題。作為應用程式開發人員,當被告知“暫時處理它”時,我們可能沒有能力修復底層基礎架構問題。這就是你想要重試的時候。

什麼時候不用

如果我們擁有可靠的且始終如一的響應式 API,則無需重試。如果響應失敗並且重試後依然不能成功響應,那我們也就不需要重試了。

大多數 API 都是一致的。這就是為什麼你需要小心這個模式:

如何使用

我們希望確保在發出請求時,不會對伺服器造成衝擊。想象一下因為負載過重造成伺服器當機的情形吧。重試將把一個已死的伺服器再埋到六英尺深的地下。出於這個原因,我們在進行後續請求時需要所謂的退避策略。我們不希望在伺服器當機的情況下仍然立即一個接一個地發出 5 個請求。我們應該錯開它們以減少 API 伺服器上的負載。

大多數情況下,我們使用指數退避來確定在傳送下一個請求之前我們應該等待多長時間。我們通常只想重試 3 次,所以這裡有一個使用不同函式的等待時間示例:

[譯] 用 API 請求製作賞心悅目的 UX

立即傳送第一個請求。它失敗了。接下來,我們需要確定在傳送第一次重試之前使用退避策略等待多長時間。讓我們看一下這些曲線,其中 X 等於我們已經傳送的重試次數。

使用我們的二次(y = x²)函式和線性(y = x)函式,在第一個等待時間內我們得到 0,即應該立即傳送下一個請求。

所以可以在執行時消除這兩個函式了。

使用指數(y = 2^x)函式和常數(y = 1)函式,我們得到 1 秒的等待時間。

常數函式使我們無法靈活處理已經傳送的重試次數,從而改變我們應該等待的時間。

這就只剩下指數函式了。讓我們編寫一個函式,來告訴我們根據已經傳送的重試次數確定等待多少秒:

[譯] 用 API 請求製作賞心悅目的 UX

簡單的 y = 2^x 函式

在編寫重試函式之前,我們想要一種方法來確定請求是否錯誤。假設狀態碼大於或等於 500 時,請求是錯誤的。這個就是我們可以為此編寫的函式了:

[譯] 用 API 請求製作賞心悅目的 UX

如果響應錯誤,我們的函式會丟擲自定義錯誤

請記住,你可能有不同的標準來確定請求是否失敗。最後,我們可以使用指數退避策略編寫重試函式:

[譯] 用 API 請求製作賞心悅目的 UX

我們使用指數退避策略重試

你會注意到我建立了一個我沒有匯出的函式(_retryWithBackoff)。使用我們的重試函式時,呼叫程式碼不能在迭代中顯式傳遞。

總結

有很多很好的防禦模式可以提供良好的使用者體驗。這三個你今天就可以使用!如果你有興趣瞭解更多,我建議閱讀 Release It!一本關於如何在構建可擴充套件軟體時解決這些確切問題的書。

如果發現譯文存在錯誤或其他需要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可獲得相應獎勵積分。文章開頭的 本文永久連結 即為本文在 GitHub 上的 MarkDown 連結。


掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章