天天看點

node mysql retry_NodeJS實作Retry重試政策和回退嘗試

需求描述

在服務端經常會遇到異常故障,對于重要業務我們會對異常進行捕獲,并進行重試或回退嘗試。

例如,短信服務。當我們調用第三方的短信服務由于網絡逾時,導緻調用API失敗無法給使用者下發驗證碼。通常,我們會使用try...catch捕獲異常,并執行一次補發。但是可能由于網絡異常再次失敗。那麼,如何實作多次重試政策呢。

實作思路

實作 retry的核心思想是,遞歸調用。

代碼實作

初級版

const retry = (retries, fn) => {

fn().catch((err) => retries > 1 ? retry(retries - 1, fn) : Promise.reject(err));

};

增強版 - 增加延遲重試

// 首先實作一個暫停函數

const pause = (duration) => new Promise((reslove) => setTimeout(reslove, duration));

const backoff = (retries, fn, delay = 500) => {

fn().catch((err) => retries>1

? pause(delay).then(() => backoff(retries-1, fn, delay))

: Promise.reject(err)

);

}

總結

在實作pause函數時,始終不明白後半部分代碼的含義,為什麼setTimeout(reslove, duration)可以直接傳一個reslove。

後來才想明白,setTimeout第一個參數是需要延遲執行的函數,而reslove本身就是一個函數。

最後,附上 setTimeout的API文檔

* `callback` 當定時器到點時要調用的函數。

* `delay` 調用 `callback` 之前要等待的毫秒數。

* `...args` 當調用 `callback` 時要傳入的可選參數

setTimeout(callback, delay[, ...args])

預定在 `delay` 毫秒之後執行的單次 `callback`。 傳回一個用于 [`clearTimeout()`](http://nodejs.cn/s/L4L2Xr) 的 `Timeout`。

`callback` 可能不會精确地在 `delay` 毫秒被調用。 Node.js 不能保證回調被觸發的确切時間,也不能保證它們的順序。 回調會在盡可能接近所指定的時間上調用。

注意:當 `delay` 大于 `2147483647` 或小于 `1` 時,`delay` 會被設為 `1`。

如果 `callback` 不是一個函數,則抛出 [`TypeError`](http://nodejs.cn/s/Z7Lqyj)

參考資料