微信小程序封装请求API-promise格式

微信小程序原生的请求API就是wx.request

wx.request({
  url: 'example.php', //仅为示例,并非真实的接口地址
  data: {
    x: '',
    y: ''
  },
  header: {
    'content-type': 'application/json' // 默认值
  },
  success (res) {
    console.log(res.data)
  }
})

有时候不能很好的适配我们的开发需求,比如我们要加一些基础url路径、请求前后的loading效果、不同接口名称下的header。而且,在success回调方法里写请求成功后的操作,看起来代码不太清晰。接下来讲一下封装的逻辑,完整代码放在最后。

第一步:在app.js同级目录下,创建一个文件夹

在utils文件夹里新建一个service.js文件,用来放封装的wx.request方法

第二步:封装wx.request方法成promise对象

使用promise对象能很好的解决回调地狱,在.then(res=>{}).catch(err=>{})中能很清晰地看出代码的逻辑

export const request = (parmas) => {
    // 返回一个promise对象
    return new Promise((resolve, reject) => {
        wx.request({
            url: parmas.url, //仅为示例,并非真实的接口地址
            data:parmas.data,
            header: {
                'content-type': 'application/json' // 默认值
            },
            success: (res)=> {
                 // 请求成功,就将成功的数据返回出去
                resolve(result)
            },
            fail: (err) => {
                reject(err)
            },
        })
    })
}

注意:success: (result) => {} 使用箭头函数,防止出现this指向错误
这样,就算是封装了一个最简单、最基础(简陋)的请求API了,在需要使用这个方法的页面的js文件中,引入它

第三步:页面中引用封装的请求API

页面

/**
 * 小程序中要引用方法,哪个页面要用,就在哪个页面引入
 */
import { request } from "../../utils/service";
Page({
  /**
   * 页面的初始数据
   */
  data: { 
  ..........
  ..........
 
 getGoodsList () {
    //因为返回的是promise对象,所以通过.then来获取resolve出来的请求成功的返回数据
    request({ url: "https://xxxtest/goods/search", data: this.QueryParams })
      .then((res) => {
        console.log(res);
    })
  }

现在,来详细扩展一下封装的请求API

1.设置基础请求路径

// 基础url
const baseUrl = "https://xxxtest"

这样,就可以简化调用这个方法时url的参数内容了,也方便统一修改开发环境地址、生产环境地址

// url: "/goods/list" ==》  url中不用再写前面的一长串了
export function getGoodsList(params) {
  return request({
    url: `/goods/list`,
    method: 'POST',
    params
  })
}

2.解构传入的参数

我们可以通过ES6中的扩展运算符,将传入到封装方法里的参数直接全部解构出来,不用再一个个获取赋值给对应的键值对了 …parmas 直接解构出传入的参数

export const request = (parmas) => {
    //设置基础请求头
    const baseUrl = "https://xxxtest"
    // 返回一个promise对象
    return new Promise((resolve, reject) => {
        /**
             *  ...parmas ===>就是将传进来的参数扩展开,一行行展示在这里面
             * 比如:传进来
             * {
             *  url:'xx',
             *  data:{key1:val1,key2:val2}
             * }
             * 那么通过  ...parmas  就会把这些内容展示到这里了
        */
        wx.request({
            ...parmas,
            // 注意,此行必须放在   ...parmas之下,才能覆盖其解构出的,传入的url:xxx参数
            url: baseUrl + parmas.url,
            success: (res)=> {
                 // 请求成功,就将成功的数据返回出去
                resolve(result)
            },
            fail: (err) => {
                reject(err)
            },
        })
    })
}

3.根据不同的url接口添加不同的header

header中的Authorization字段一般存储token,用来做身份验证,但有些请求不需要携带token,所以这个封装的API中需要能根据传入的url来判断什么时候该给请求添加上token,什么时候不用可以添加。

export const request = (parmas) => {
/**
 *   根据不同的url接口,来设置不同的header请求头
 **  判断 url中是否带有 /my/ 请求的是私有的路径 带上header token
 **  { ...parmas.header }  ==> 先解构出传进来的header对象,然后再往这个对象里面添加Authorization字段数据,这样即使有传入header的其他字段也能保留下来
 *   如果传入的parmas参数中没有header,那myHeader就是个空的对象 {} 因为啥都没有
 */
let myHeader = { ...parmas.header };
//通过includes方法查找字符串中是否包含指定内容,进而判断是否要添加token
if (parmas.url.includes("/neddToken/")) {
    // 往myHeader这个对象里插入键值对 带上Storage中存储的token
    myHeader["Authorization"] = wx.getStorageSync("token");
}

//设置基础请求头
const baseUrl = "https://xxxtest"
// 返回一个promise对象
return new Promise((resolve, reject) => {
    wx.request({
        ...parmas,
        url: baseUrl + parmas.url,
        /**
         * !可以设置上默认的content-type,然后再扩展出传入的myHeader,如果传入的myHeader为空,那header就还是默认的content-type一个键值对
         * !{ 'content-type': 'application/json', ...myHeader } ==》 扩展出myHeader这 个对象中的键值对;
         */
        header: { 'content-type': 'application/json', ...myHeader },
        success: (res)=> {
             // 请求成功,就将成功的数据返回出去
            resolve(result)
        },
        fail: (err) => {
            reject(err)
        },
    })
})
}

此时,在使用这个封装的API的时候,就可以对header进行设置了,例如:

request({
  url: '/neddToken/home/swiperdata',
  // 使用的时候也可以传入一些header的字段
  header: {
    'content-type': 'application/json',
    'Date': 'Tue, 15 Nov 2021 08:12:31 GMT'
  },
  method: 'GET',
}).then((result) => {
   console.log(result)
})

此时,因为请求url中含有【neddToken】,就会在header中插入token

4.添加请求发起时页面loading效果

当页面在加载数据的时候,最好要有一个loading的提示,同时有遮罩,防止用户乱点

所以,就需要在封装的API中加入微信小程序的wx.showLoading遮罩层了

    // 显示加载中loading效果
    wx.showLoading({
        title: "加载中",
        mask: true  //开启蒙版遮罩
    });
    ...
    ...
    //  关闭正在等待loading效果
    wx.hideLoading();

如果直接在封装的API的开始加上loading,在请求结束加上隐藏loading效果,那乍看一下,好像没错,但是如果一个页面同时触发了多个请求呢?比如打开一个页面,同时加载多个模块,需要从不同的接口请求数据,那就会使用多次这个封装的API。

此时,就会出现,第一个请求结束,直接关闭了loading效果,而后面几个请求就没有loading效果的遮罩了。

所以,需要在封装的js文件中设置一个全局变量,每次调用这个封装的文件时,就对这个变量++,每次请求结束,返回数据出去的时候,就对这个变量–,最后判断一下这个变量是否为0(也就是所有请求的结束了),在决定是否关闭loading效果


let ajaxTimes = 0
export  const request = (params)=>{
	//有调用的时候增加全局变量,用于判断有几个请求
	ajaxTimes++
	wx.showLoading({
        title: "加载中",
        mask: true  //开启蒙版遮罩
    });
}

complete:()=>{
	//每次请求结束后就减少全局变量,当为0时,就表示这是最后一个请求了
	ajaxTimes--
	if(ajaxTimes ==0) {
		wx.hideLoading();
	}
}

完整的封装请求API的js文件

// 同时发送异步代码的次数
let ajaxTimes = 0;
export const request = (parmas) => {
    // 当有地方调用请求方法的时候,就增加全局变量,用于判断有几个请求了
    ajaxTimes++;
    // 显示加载中loading效果
    wx.showLoading({
        title: "加载中",
        mask: true  //开启蒙版遮罩
    });
    let myHeader = { ...parmas.header };
    if (parmas.url.includes("/neddToken/")) {
        // 往myHeader这个对象里插入键值对 带上Storage中存储的token
        myHeader["Authorization"] = wx.getStorageSync("token");
    }
    // 基础url
    const baseUrl = "https://xxxtest"
    return new Promise((resolve, reject) => {
        wx.request({
            ...parmas,
            url: baseUrl + parmas.url,
            header: { 'content-type': 'application/json', ...myHeader },
            success: (result) => {
                // 请求成功,就将成功的数据返回出去
                resolve(result)
            },
            fail: (err) => {
                reject(err)
            },
            // 不管请求成功还是失败,都会触发
            complete: () => {
                ajaxTimes--;
                // 此时就可以关闭loading效果了
                if (ajaxTimes === 0) {
                    //  关闭正在等待loading效果
                    wx.hideLoading();
                }
            }
        });
 
    })
}
 

进一步完善封装请求

如果一个接口在多个页面中都需求,那么直接在页面引入请求会比较麻烦,不利于后期维护,可以把请求放在单独的文件里来统一维护。
在api文件夹下创建一个index.js文件,用来存放项目中的接口请求

index.js文件

import request from '@/utils/service'

// 获取商品信息
export function getGoodsList(params) {
  return request({
    url: `https://xxxtest/goods/list`,
    method: 'POST',
    params
  })
}

页面

/**
 * 小程序中要引用方法,哪个页面要用,就在哪个页面引入
 */
import { api } from "../../api/index";
Page({
  /**
   * 页面的初始数据
   */
  data: { 
  ..........
  ..........
 
 getGoodsList () {
    //因为返回的是promise对象,所以通过.then来获取resolve出来的请求成功的返回数据
    api.getGoodsList({ data: this.QueryParams })
      .then((res) => {
        console.log(res);
    })
  }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/754488.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

mac压缩解压工具:Keka for Mac 中文版下载

Keka是一个压缩软件,适用于macOS操作系统。它的界面友好,功能强大,可以帮助用户轻松地压缩和解压文件。以下是Keka的一些特点: 界面简洁:Keka的设计风格与macOS系统保持一致,操作界面简洁明了,…

【内网安全】组策略同步-不出网隧道上线-TCP转ICMP

目录 域控-防火墙-组策略对象同步演示1、打开组策略管理,新建一个GPO连接 取名fhq(防火墙)2、编辑fhq并设置防火墙状态3、命令:gpupdate/force 更新策略4、域控主机新增规则5、域内用户主机更新规则 域控-防火墙-组策略不出网上线演示 ICMP协议上线&…

任意密码重置漏洞

文章目录 1. 任意密码重置漏洞原理2. 任意密码重置漏洞产生原因3. 任意密码重置漏洞场景3.1 验证码爆破3.2 验证凭证回传3.3 验证凭证未绑是用户3.4 跳过验证步骤3.5 凭证可预测3.6 同时向多个账户发送凭证 4. 任意密码重置经典案例4.1 中国人寿某重要系统任意账户密码重置4.2 …

命令行中关于windows hash md5 , mac hash md5 , linux hash md5 文件校验方式

md5, sha-1 ,sha256. windows certutil -hashfile filename md5certutil -hashfile filename sha1certutil -hashfile filename sha256macos 平台 md5 filenameshasum -a 1 filenameshasum -a 256 filenamelinux 平台 md5sum filenameshasum -a 1 fil…

Windows平台使用S3Browser连接兼容的对象存储

本文记录了在Windows平台使用S3Browser连接兼容的对象存储的过程 一、安装S3Browser 1、下载 S3Browser官网:https://s3browser.com/ 直接下载:https://s3browser.com/download/s3browser-11-6-7.exe 2、安装 3、同意授权后确定安装目录 4、勾选立即…

VsCode:配置TypeScript开发环境

一、前提 电脑已经安装了npm 何如安装npm,请点击查看Node.js、npm常用命令、安装多个node版本 提醒:下文讲解操作是在mac 系统进行的,TypeScript简称:ts 二、安装TypeScript 在终端里执行命令:npm install -g typescr…

uni-appx使用form表单页面初始化报错

因为UniFormSubmitEvent的类型时 e-->detail-->value,然后没有了具体值。所以页面初始化的时候 不能直接从value取值,会报错找不到 所以form表单里的数据我们要设置成一个对象来存放 这个问题的关键在于第22行代码 取值: 不能按照点的方式取值 …

【CT】LeetCode手撕—300. 最长递增子序列

目录 题目1- 思路2- 实现⭐300. 最长递增子序列——题解思路 3- ACM 实现 题目 原题连接&#xff1a;300. 最长递增子序列 1- 思路 模式识别&#xff1a;最长递增子序列——> 利用动规五部曲 解决 ——> 借助 i 和 j 指针&#xff0c;其中 j < i 动规五部曲 1.定义…

Ubuntu安装、更新和删除软件

Ubuntu安装、更新和删除软件 问题命令行直接安装、更新和删除软件命令行直接安装软件命令行直接更新软件命令行直接删除软件 手动下载后命令行安装、更新和删除软件手动下载后命令行安装软件手动下载后命令行更新软件手动下载后命令行删除软件 手动下载后在桌面环境下安装、更新…

grpc学习golang版( 八、双向流示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、编写server服务端四、编写client客…

压缩pdf在线工具,压缩pdf大小的软件

如何有效地压缩PDF文件大小却是个问题&#xff0c;为了获得最佳的压缩效果&#xff0c;我们必须依赖专业的压缩工具&#xff0c;采用错误的方法可能会对文件内容产生负面影响&#xff0c;甚至导致文件无法打开&#xff0c;今天&#xff0c;我将分享一些独特的压缩技巧&#xff…

【语言模型】深入探索语言模型中的神经网络算法:原理、特点与应用

随着人工智能技术的飞速发展&#xff0c;神经网络算法在语言模型中的应用日益广泛&#xff0c;为自然语言处理领域带来了革命性的变革。本文将深入探讨当前语言模型中常用的几种神经网络算法&#xff0c;包括全连接神经网络、卷积神经网络、循环神经网络、长短期记忆网络、门控…

ffmpeg使用png编码器把rgb24编码为png图像

version #define LIBAVUTIL_VERSION_MAJOR 58 #define LIBAVUTIL_VERSION_MINOR 12 #define LIBAVUTIL_VERSION_MICRO 100 note 不使用AVOutputFormat code void CFfmpegOps::EncodeRGB24ToPNG(const char *infile, const char *width_str, const char *height_str, c…

【学习笔记】爱立信SPO 1400 CRAFT软件基础知识4——图形用户界面之通知列表和状态栏

一、前期准备 提示&#xff1a;下面所有学习内容都是基于以下条件完成的 条件1.已经正确安装并正常运行SPO 1400 CRAFT软件&#xff08;以下简称LCT&#xff09; 条件2.确认已正确使用爱立信SPO 1400 CRAFT软件通过网络登录设备&#xff08;以下简称NE&#xff09; 具体登录…

嵌入式应用开发屏幕教程8080并口通信

目录 #8080相关概念介绍 #8080并行通信硬件连接部分 #并行通信硬件电路连接图 #并行通信读数据规定 #并行通信写数据规定 #8080相关概念介绍 通信协议分为串行通信协议&#xff0c;并行通信协议&#xff0c;而本章所讲的8080是一种并行通信协议&#xff0c;并行通信协议 Pa…

Git使用过程中涉及的几个区域

一. 简介 Git 是一个开源的分布式版本控制系统&#xff0c;可以有效、高速的处理从很小到非常大的项目版本管理&#xff0c;也是 Linus Torvalds 为了帮助管理 Linux内核开发而开发的一个开放源码的版本控制软件。 本文简单了解一下 git涉及的几个部分&#xff0c;以及git 常…

老无忧,成熟人士都在玩的社交app

随着互联网向不同年龄群体的进一步渗透&#xff0c;越来越多大龄人士逐步在传统以年轻人为主的平台中搭建起自己的空间&#xff0c;对缔结社交关系的需求也变得强烈起来。老无忧无忧交友app应运而生&#xff0c;于2024年6月1日正式上线&#xff08;以下简称“老无忧”&#xff…

step6:改用单例模式

文章目录 文章介绍codemain.cppSerialPort.qmlSerialPortHandler.h 文章介绍 案例MF改为单例模式 参考之前写过的关于单例模式的文章单例模式1、单例模式2 code main.cpp qmlRegisterSingletonType(“com.example.serialport”, 1, 0, “SerialPortHandler”, SerialPortHan…

c++ 设计模式 的课本范例(上)

( 0 ) 这里补充面向对象设计的几个原则&#xff1a; 开闭原则 OCP &#xff1a; 面向增补开放&#xff0c;面向代码修改关闭。其实反映到代码设计上就是类的继承&#xff0c;通过继承与多态&#xff0c;可以不修改原代码&#xff0c;又增加新的类似的功能。 依赖倒置原则 Depen…

JavaSE:多态

向上转型&#xff1a; 先看一段代码&#xff1a; 为何Animal animalnew Dog这个代码不报错。就是因为使用了向上转型&#xff1a;父类引用引用子类对象 向上转型一共有三种方式可以实现向上转型&#xff1a;1.直接赋值&#xff0c;2.通过传参&#xff0c;3.返回值 1.直接赋值…