- 原文地址:Crafting beautiful UX with API requests
- 原文做者:Ryan Baker
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:MeFelixWang
- 校對者:sunhaokk
試圖控制超出 Web 應用程序範圍的體驗一般是過後的想法。工程師忘記了處理從 API 請求數據時可能會遇到的全部麻煩事情。在本文中,我將爲你提供三種模式(包括代碼片斷),以使你的應用程序能彈性應對不可預測的情形。前端
讓你的用戶和這個愚蠢的人類同樣快樂android
超時是一種簡單的模式。簡而言之,就是:「若是你的反應比我想要的慢,請取消個人請求」。ios
你應該使用超時來設置你但願請求耗用的時長上限。有什麼可能會使你的 API 響應時間比預期的長?這取決於你的 API,但如下是一些現實場景的示例:git
你的服務器與數據庫進行通訊。數據庫宕機了,但服務器的鏈接超時爲 30 秒。服務器將花費完整的 30 秒來肯定它沒法與數據庫通訊。這意味着你的用戶將等待 30 秒!github
你使用了 AWS 負載均衡器,其背後的服務器已宕機(不管出於何種緣由)。你將負載均衡器超時保留爲默認值 60 秒,而且在失敗以前一直嘗試鏈接服務器。數據庫
若是你的 API 已知響應時間具備可變性,則不該使用超時。一個很好的例子多是返回報告數據的 API。請求一天的數據是快速的(多是亞秒響應時間),但請求八個月的數據大約須要 12 秒。後端
若是你沒法肯定對於請求應該花多長時間的可靠上限,則不要使用超時。api
假設你的應用程序中有一個方法能夠作到這一點:服務器
示例方法可能存在於 React 組件內部架構
你知道你的 API 在 99% 的時間裏會在 3 秒內響應。假設你使用 Promises 從 API 獲取數據,你能夠這樣作:
爲你的 API 調用配置超時
注意:你可能用於進行 API 調用的大多數庫都具備超時配置。請使用你工具的內置功能,而不是本身編寫
最短等待時間也是一種簡單的模式。它與超時相反:它能夠保護你的應用免受 API 快速響應的影響。
若是要向用戶顯示加載狀態,則最短等待時間是一種很是好的模式,但 API 可能會快速響應。結果就是用戶會看到加載狀態,接着數據「彈出」進入視圖,而後其才能專一於想作的事。
這不是一個良好的體驗。若是你顯示加載狀態,你是在告訴用戶「稍等,咱們正在處理些事兒,咱們會立刻回來」。這讓用戶能夠喘口氣,也許查看一下他們的手機 —— 若是用戶看到加載狀態,那麼用戶但願等待。若是你獲取太快,那就太突兀了。你打斷了她的休息,讓她變得緊張。
當你擁有響應速度始終很是快的 API 時,最好避免使用最短等待模式。不要爲了添加加載狀態而添加,若是不須要,就不要讓用戶等待。
使用上面的示例,你能夠編寫代碼「在這兩件事完成以前不作任何事」,以下所示:
強制請求的最短等待時間
重試模式是我將要介紹的最複雜的模式。基本的想法是,若是獲得錯誤的響應,咱們想要重試幾回請求。這是一個很是簡單的想法,但在使用它時須要記住一些注意事項。
當你向可能發生間歇性故障的 API 發出請求時,你會但願使用此方法。當知道請求會不時由於沒法控制的問題而失敗時咱們幾乎都但願重試。
就我而言,當我知道我正在發出使用特定數據庫的請求時,我會常用它。訪問該數據庫時,有時它會失敗。是的,這很糟糕。是的,這是咱們應該解決的問題。做爲應用程序開發人員,當被告知「暫時處理它」時,咱們可能沒有能力修復底層基礎架構問題。這就是你想要重試的時候。
若是咱們擁有可靠的且始終如一的響應式 API,則無需重試。若是響應失敗而且重試後依然不能成功響應,那咱們也就不須要重試了。
大多數 API 都是一致的。這就是爲何你須要當心這個模式:
咱們但願確保在發出請求時,不會對服務器形成衝擊。想象一下由於負載太重形成服務器宕機的情形吧。重試將把一個已死的服務器再埋到六英尺深的地下。出於這個緣由,咱們在進行後續請求時須要所謂的退避策略。咱們不但願在服務器宕機的狀況下仍然當即一個接一個地發出 5 個請求。咱們應該錯開它們以減小 API 服務器上的負載。
大多數狀況下,咱們使用指數退避來肯定在發送下一個請求以前咱們應該等待多長時間。咱們一般只想重試 3 次,因此這裏有一個使用不一樣函數的等待時間示例:
當即發送第一個請求。它失敗了。接下來,咱們須要肯定在發送第一次重試以前使用退避策略等待多長時間。讓咱們看一下這些曲線,其中 X 等於咱們已經發送的重試次數。
使用咱們的二次(y = x²)函數和線性(y = x)函數,在第一個等待時間內咱們獲得 0,即應該當即發送下一個請求。
因此能夠在運行時消除這兩個函數了。
使用指數(y = 2^x)函數和常數(y = 1)函數,咱們獲得 1 秒的等待時間。
常數函數使咱們沒法靈活處理已經發送的重試次數,從而改變咱們應該等待的時間。
這就只剩下指數函數了。讓咱們編寫一個函數,來告訴咱們根據已經發送的重試次數肯定等待多少秒:
簡單的 y = 2^x 函數
在編寫重試函數以前,咱們想要一種方法來肯定請求是否錯誤。假設狀態碼大於或等於 500 時,請求是錯誤的。這個就是咱們能夠爲此編寫的函數了:
若是響應錯誤,咱們的函數會拋出自定義錯誤
請記住,你可能有不一樣的標準來肯定請求是否失敗。最後,咱們可使用指數退避策略編寫重試函數:
咱們使用指數退避策略重試
你會注意到我建立了一個我沒有導出的函數(_retryWithBackoff
)。使用咱們的重試函數時,調用代碼不能在迭代中顯式傳遞。
有不少很好的防護模式能夠提供良好的用戶體驗。這三個你今天就可使用!若是你有興趣瞭解更多,我建議閱讀 Release It!一本關於如何在構建可擴展軟件時解決這些確切問題的書。
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。