• 原生微信小程序中进行 API 请求


    原生微信小程序中进行 API 请求

    当在原生微信小程序中进行 API 请求时,封装请求可以提高代码的可维护性和可扩展性。在本篇博客中,我们将一步步介绍如何进一步封装请求,并添加请求超时、拦截器和请求取消功能。

    在这里插入图片描述

    第一步:基本请求封装

    首先,我们创建一个用于发送 HTTP 请求的基本封装。在微信小程序中,我们使用 wx.request 发送请求,这里我们将它封装成一个 Promise 风格的函数:

    // request.js
    
    function request(url, method, data, header = {}) {
      return new Promise((resolve, reject) => {
        wx.request({
          url: url,
          method: method,
          data: data,
          header: {
            'content-type': 'application/json', // 根据需求设置请求头
            ...header,
          },
          success: (res) => {
            if (res.statusCode === 200) {
              resolve(res.data);
            } else {
              reject(new Error('请求失败'));
            }
          },
          fail: (err) => {
            reject(err);
          },
        });
      });
    }
    
    export function get(url, data = {}, header = {}) {
      return request(url, 'GET', data, header);
    }
    
    export function post(url, data = {}, header = {}) {
      return request(url, 'POST', data, header);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    这段代码中,我们定义了两个函数 getpost,分别用于发送 GET 和 POST 请求,并返回一个 Promise,以便在请求成功或失败时进行处理。

    第二步:请求超时

    为了实现请求超时功能,我们可以使用 Promise 的 Promise.race 方法。我们创建一个新的 Promise,设置一个超时时间,然后将它与实际请求的 Promise 进行竞争。如果超时时间内请求未完成,我们可以取消请求并抛出一个超时错误。

    // request.js
    
    function requestWithTimeout(url, method, data, header = {}, timeout = 5000) {
      return new Promise((resolve, reject) => {
        const timer = setTimeout(() => {
          reject(new Error('请求超时'));
        }, timeout);
    
        wx.request({
          url: url,
          method: method,
          data: data,
          header: {
            'content-type': 'application/json', // 根据需求设置请求头
            ...header,
          },
          success: (res) => {
            clearTimeout(timer);
            if (res.statusCode === 200) {
              resolve(res.data);
            } else {
              reject(new Error('请求失败'));
            }
          },
          fail: (err) => {
            clearTimeout(timer);
            reject(err);
          },
        });
      });
    }
    
    export function getWithTimeout(url, data = {}, header = {}, timeout = 5000) {
      return requestWithTimeout(url, 'GET', data, header, timeout);
    }
    
    export function postWithTimeout(url, data = {}, header = {}, timeout = 5000) {
      return requestWithTimeout(url, 'POST', data, header, timeout);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    第三步:请求拦截器和响应拦截器

    拦截器允许我们在请求发出前和响应返回后进行一些自定义操作,例如添加请求头、记录日志或处理错误信息。我们可以通过使用函数链来实现这一功能。首先,我们创建两个空数组 requestInterceptorsresponseInterceptors,用于存储拦截器函数。然后,我们通过一个函数来添加拦截器,每个拦截器都是一个函数,接受 config(请求配置)或 response(响应对象)作为参数,并可以对它们进行修改。最后,在请求或响应时,我们通过遍历这些拦截器数组,依次执行它们。

    // request.js
    
    let requestInterceptors = [];
    let responseInterceptors = [];
    
    // 添加请求拦截器
    export function addRequestInterceptor(interceptor) {
      requestInterceptors.push(interceptor);
    }
    
    // 添加响应拦截器
    export function addResponseInterceptor(interceptor) {
      responseInterceptors.push(interceptor);
    }
    
    function executeInterceptors(interceptors, data) {
      return interceptors.reduce((prevData, interceptor) => {
        return interceptor(prevData);
      }, data);
    }
    
    function request(url, method, data, header = {}, timeout = 5000) {
      // ...
      
      // 执行请求拦截器
      config = executeInterceptors(requestInterceptors, config);
      
      // ...
      
      // 执行响应拦截器
      responseData = executeInterceptors(responseInterceptors, responseData);
      
      // ...
    }
    
    // ...
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    你可以使用 addRequestInterceptoraddResponseInterceptor 函数来添加自定义的拦截器,例如:

    import { addRequestInterceptor, addResponseInterceptor } from './request';
    
    // 添加请求拦截器
    addRequestInterceptor((config) => {
      // 在请求发出前进行一些操作,例如添加请求头
      config.header['Authorization'] = 'Bearer ' + getToken();
      return config;
    });
    
    // 添加响应拦截器
    addResponseInterceptor((response) => {
      // 在响应返回后进行一些操作,例如处理错误信息
      if (response.statusCode !== 200) {
        throw new Error('请求失败');
      }
      return response.data;
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    第四步:请求取消

    为了实现请求取消功能,我们可以使用 Axios 风格的取消令牌(CancelToken)。我们需要创建一个 CancelToken 对象,并将它包含在请求的配置中。然后,在需要取消请求的地方,我们可以调用 cancel 方法取消请求。

    // request.js
    
    let cancelToken = new wx.miniProgram.CancelToken();
    
    function requestWithCancel(url, method, data, header = {}, timeout = 5000) {
      return new Promise((resolve, reject) => {
        wx.request({
          url: url,
          method: method,
          data: data,
          header: {
            'content-type': 'application/json', // 根据需求设置请求头
            ...header,
          },
          cancelToken: cancelToken.token, // 设置取消令牌
          success: (res) => {
            if (res.statusCode === 200) {
              resolve(res.data);
            } else {
              reject(new Error('请求失败'));
            }
          },
          fail: (err) => {
            reject(err);
          },
        });
      });
    }
    
    // 取消请求
    export function cancelRequest() {
      cancelToken.cancel('请求取消');
    }
    进一步封装请求超时、拦截器和请求取消功能可以提高代码的灵活性和可维护性。以下是一个更完整的原生微信小程序 API 请求封装,包括这些功能:
    
    javascript
    Copy code
    // api.js
    
    // 创建一个取消请求的 CancelToken
    const CancelToken = wx.miniProgram.CancelToken;
    
    // 默认配置
    const defaultConfig = {
      baseURL: '', // 请求基础 URL
      timeout: 5000, // 请求超时时间(毫秒)
    };
    
    // 请求拦截器
    function requestInterceptor(config) {
      // 在请求发送之前可以进行一些操作,例如添加请求头
      config.header = {
        'content-type': 'application/json',
        ...config.header,
      };
      return config;
    }
    
    // 响应拦截器
    function responseInterceptor(response) {
      // 在收到响应后可以进行一些操作,例如处理错误信息
      if (response.statusCode !== 200) {
        throw new Error('请求失败');
      }
      return response.data;
    }
    
    // 创建请求实例
    const instance = wx.request.create({
      timeout: defaultConfig.timeout,
      header: {
        'content-type': 'application/json',
      },
    });
    
    // 发送请求的函数
    function sendRequest(config) {
      const { baseURL, timeout, ...restConfig } = { ...defaultConfig, ...config };
      const { url, method, data, params, cancelToken, ...otherConfig } = restConfig;
    
      // 合并请求 URL
      const fullURL = `${baseURL}${url}`;
    
      // 创建 CancelToken 实例
      const source = CancelToken.source();
    
      // 设置取消令牌
      otherConfig.cancelToken = source.token;
    
      // 发送请求
      return instance({
        url: fullURL,
        method,
        data,
        params,
        ...otherConfig,
      })
        .then(responseInterceptor)
        .catch((error) => {
          if (wx.miniProgram.isCancel(error)) {
            // 请求被取消
            console.log('请求已取消');
          } else {
            // 请求发生错误
            console.error('请求失败:', error);
          }
          throw error;
        });
    }
    
    export { sendRequest, requestInterceptor, responseInterceptor };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106
    • 107
    • 108
    • 109
    • 110
    • 111

    在上面的代码中,添加了以下功能:

    • 请求超时:可以通过设置 timeout 来指定请求超时时间,如果请求在规定时间内未完成,将会被取消。

    • 请求拦截器和响应拦截器:可以在发送请求前和处理响应后进行一些自定义操作,例如添加请求头或处理错误信息。

    • 请求取消:我们使用 Axios 的取消令牌(CancelToken)来支持请求取消功能。可以在请求配置中设置 cancelToken,然后在需要取消请求的地方调用 source.cancel()。

    • 使用这个进一步封装的请求函数 sendRequest,你可以在项目中更加灵活地处理网络请求,同时在拦截器中进行自定义操作,以满足不同场景的需求。在小程序的页面中,导入 sendRequest 并使用它来发起请求即可。
      在这里插入图片描述
      以上就是原生微信小程序中进行 API 请求时感谢大家的阅读
      如碰到其他的问题 可以私下我 一起探讨学习
      如果对你有所帮助还请 点赞 收藏谢谢~!
      关注收藏博客 作者会持续更新…

  • 相关阅读:
    使用SpringEvent事件通知做异步消息处理
    OpenGLES:3D立方体纹理贴图
    nginx负载均衡配置无效解决记录
    HarmonyOS NEXT应用开发之预加载so并读取RawFile文件
    transformer一统天下?depth-wise conv有话要说
    Redis分布式锁
    java和vue开发的电子书系统自动检测敏感词小说网站
    海康威视嵌入式软件一面(技术面)
    【Java入门每日一练】使用DFS深度优先遍历文件夹
    持续集成和持续部署(CI/CD)
  • 原文地址:https://blog.csdn.net/qq2754289818/article/details/132900313