js 使用 Promise 实现 Fetch 请求超时重试 All In One


js 使用 Promise 实现 Fetch 请求超时重试 All In One

Using Promises to implement Fetch request timeout retry

"use strict";

/**
 *
 * @author xgqfrms
 * @license MIT
 * @copyright xgqfrms
 * @created 2020-11-20
 * @modified 2022-03-20
 *
 * @description js 使用 Promise 实现 Fetch 请求超时重试
 * @description
 * @difficulty Medium
 * @complexity O(n)
 * @time O(n)
 * @augments
 * @example
 * @link https://www.cnblogs.com/xgqfrms/p/16038719.html
 * @link https://www.cnblogs.com/xgqfrms/p/14016391.html
 * @solutions
 *
 * @best_solutions
 *
 */

const log = console.log;



function maxRequest(url = ``, times = 3) {
  // 1. 闭包,保存私有属性
  function autoRetry (url, times) {
    console.log('times = ', times);
    times--;
    // 2. fetch 本身返回值就是 Promise,不需要再次使用 Promise 包裹
    return fetch(url).then(value => {
        if(value.status === 200) {
          console.log(`? OK`, value);
          // 3. 手动返回 Promise 的 value, 没有返回值 默认返回 undefined
          return value;
        } else {
          throw new Error(`?  http code error: ${value.status }`);
        }
      }).catch((err) => {
        console.log(`?  Error`, err);
        if (times < 1) {
          // 4. 方便后续的 thenable 处理 error
          throw new Error('??  over max request times!');
        } else {
          // 5. 返回递归方法 
          return autoRetry(url, times);
        }
      });
  }
  // 6. 返回一个 Promise 的结果 (成功 Promise 或失败 Promise)
  return autoRetry(url, times);
}

// error test case
maxRequest(`https://cdn.xgqfrms.xyz/json/badges.js`)
  .then(res => res.json())
  .then(json=> console.log('json =', json))
  .catch(err => console.error(`err =`, err))
  .finally(() => {
      console.log('??  whatever close loading...');
  });

// sucess test case
maxRequest(`https://cdn.xgqfrms.xyz/json/badges.json`)
  .then(res => res.json())
  .then(json=> console.log('json =', json))
  .catch(err => console.error(`err =`, err))
  .finally(() => {
      console.log('??  whatever close loading...');
  });

Promise then & return value

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#return_value

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises

Promise constructor antipattern

Promise 构造函数 反模式

function autoRetry (url, times) {
  return new Promise((resolve, reject) => {
    // fetch(url).then...
  });
}

function autoRetry (url, times) {
  return new Promise((resolve, reject) => {
    // Promise.resolve(fetch(url).then...)
  });
}

bad demos

function maxRequest(url = ``, times = 3) {
  // 闭包
  function autoRetry (url, times) {
    console.log('times = ', times);
    times--;
    return new Promise((resolve, reject) => {
      Promise.resolve(fetch(url)).then(value => {
        if(value.status === 200) {
          console.log(`? OK`, value);
          resolve(value);
        } else {
          throw new Error(`?  http code error: ${value.status }`);
        }
      }).catch((err) => {
        console.log(`?  Error`, err);
        if (times < 1) {
          reject('??  over max request times!');
        } else {
          autoRetry(url, times);
        }
      });
    });
  }
  return autoRetry(url, times);
}


function maxRequest(url = ``, times = 3) {
  // 闭包
  function autoRetry (url, times) {
    console.log('times = ', times);
    times--;
    return new Promise((resolve, reject) => {
      Promise.resolve(fetch(url).then(value => {
        if(value.status === 200) {
          console.log(`? OK`, value);
          resolve(value);
        } else {
          throw new Error(`?  http code error: ${value.status }`);
        }
      }).catch((err) => {
        console.log(`?  Error`, err);
        if (times < 1) {
          reject('??  over max request times!');
        } else {
          autoRetry(url, times);
        }
      }));
    });
  }
  return autoRetry(url, times);
}


https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it

fix: Uncaught (in promise) ?

https://stackoverflow.com/questions/71562261/error-message-uncaught-in-promise-but-i-cant-find-whats-wrong-with-that-af#

refs

https://javascript.info/async


Flag Counter

?xgqfrms 2012-2020

www.cnblogs.com/xgqfrms 发布文章使用:只允许注册用户才可以访问!

原创文章,版权所有??xgqfrms, 禁止转载 ???,侵权必究??!