Node.js方法錯誤自動重試的實現

在使用Node.js實現爬蟲、檢測等功能時,經常會遇到大量網絡請求的情況,這時很容易因爲超時而使得請求失敗。爲令結果正確,我們一般會設置一定的失敗重試次數,以避免因網絡波動引起的失敗。若多次嘗試最終失敗,才拋出錯誤。

下面上一段代碼:

/**
 * 包裹方法,使其自動錯誤重試
 * 只能包裹返回Promise的方法
 * 返回promise,可以獲取成功的返回值,或最後失敗的err
 * 需要運行環境支持ES6的Promise語法,或者使用Bluebird庫
 * @param func
 * @param retryMax
 * @returns {funcR}
 */
function autoRetry(func, retryMax) {
  retryNum = 0;
  let funcName = func.toString().match(/function (\w+)\(/)[1];
  return funcR = function () {
    let params = arguments;
    return new Promise((resolve, reject) => {
      func(...params).then(result => {
        resolve(result);
      }).catch(err => {
        if (retryNum < retryMax) {
          retryNum ++;
          console.warn(`[autoRetry] Catched error when ${funcName}() : ${err.message}. Retry ${retryNum} time...`);
          resolve(funcR(...params));
        } else {
          reject(err);
        }
      });
    });
  };
}

使用起來很簡單。下面舉一個例子:

// 這是一個標準的Promise化的方法
function foo (param) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      try{
        JSON.parse('{{'); // 執行到這裏會報錯
        return resolve(param);
      } catch (err) {
        return reject(err);
      }
    }, 1000);
  })
}

// 使用autoRetry()包裹方法,並給出最大重試次數(執行數=重試次數+1)
foo = autoRetry(foo, 3);

// 執行並獲取結果/捕獲錯誤
foo(123)
  .then(r => {
    console.log('成功返回:');
    console.log(r)
  })
  .catch(e => {
    console.log('最後錯誤:');
    console.log(e)
  })

// 也可以這樣寫
(async function (){
    try {
        let result = await foo(123);
    } catch (e) {
        console.log(e);
    }
})();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章