• 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://www.cnblogs.com/xgqfrms/p/14016391.html

    https://www.cnblogs.com/xgqfrms/p/13414614.html

    https://javascript.info/async



    ©xgqfrms 2012-2020

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

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


  • 相关阅读:
    python pytest全局用例共用之conftest.py详解
    mybatis mapper文件中select标签参数汇总
    mybatis整合redis实现二级缓存(转载)
    代码智能---aiXcoder插件
    mybatis运行原理及源码流程分析
    linux关闭防火墙
    mysql 锁
    mysql 性能低下的分析
    针对msyql的like中 两边都不得不使用% 的场景分析
    mysql 相关文件路径、配置
  • 原文地址:https://www.cnblogs.com/xgqfrms/p/16038719.html
Copyright © 2020-2023  润新知