微信小程序封装请求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中存储的tokenmyHeader["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中存储的tokenmyHeader["Authorization"] = wx.getStorageSync("token");}// 基础urlconst 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);})}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

通过Nginx实战讲解HTTP的301和302状态码的区别

通过Nginx实战讲解HTTP的301和302状态码的区别 1. 简介2. 301永久重定向3. 302临时重定向1. 简介 HTTP状态码中,301和302都是网页重定向跳转。301重定向是一种永久重定向,而302跳转是暂时的跳转    ● 为什么需要重定向:    网站是会被大量用户收藏在自己的浏览器收藏夹…

小红书营销:解锁企业增长新引擎,与小红书集成实现精准获客

在数字化营销的新时代,小红书以其独特的社区文化和精准的用户定位,成为了品牌和企业争相入驻的热门平台。今天将探讨如何通过小红书平台进行营销获客,并强调与企业集成的重要性,以实现更高效的品牌增长。 一、小红书营销的独特优…

基于 MHA 的 MySQL 高可用主从架构

Author:Arsen Date:2024/06/25 目录 一、前言1.1 概述1.2 组件1.3 流程 二、环境三、部署3.1 基本环境3.1.1 hosts 配置3.1.2 配置 SSH 免密访问 3.2 MySQL 主从3.2.1 基础环境配置3.2.2 启动 MySQL 实例3.2.3 配置 MySQL 主从3.2.4 MySQL 主从同步验证 …

Calibre - 合并电子书(EpubMerge)

这里使用 Calibre 软件和 EpubMerge 插件 EpubMerge github : https://github.com/JimmXinu/EpubMerge 1、安装 Merge 插件 安装后需要重启 calibre 2、查看设置 4 3、选中文件、开始合并 合并完成后,会弹窗窗口,来编辑 合辑的元信息 完成…

基于python的随机森林多分类模型

1.随机森林多分类模型 1.1 基本原理 随机森林(Random Forest)是一种基于决策树的集成学习方法,它通过将多个决策树进行组合,以投票或平均的方式得到最终的预测结果。在多分类问题中,随机森林通过构建多个决策树&#…

开发RpcProvider的网络服务

首先更改src的CMakeLists.txt的内容为: #当前目录的所有源文件放入SRC_LIST aux_source_directory(. SRC_LIST)#生成SHARED动态库 #add_library(mprpc SHARED ${SRC_LIST})#由于muduo是静态库,为了使用muduo,将mprpc也生成为静态库 add_libr…

A股周一走势历史罕见,你知道是为什么吗?

今天的A股,让人历史罕见,你知道是为什么吗?盘面出现2个重要信号,一起来看看: 1、今天大盘低开低走,跌懵了,两市板块全部在等待翻红,这让人历史罕见。 2、盘面出现2个重要信号&#x…

java —— 网络编程(UDP)

一、InetAddress 类 InetAddress address1InetAddress.getLocalHost(); 该命令用于获取本机主机信息,返回主机名与 IP 地址,不过如果本机有多个网卡的话,返回的 IP 地址并不一定是目前正在联网的那个。 InetAddress address2InetAddress.g…

【计算机毕业设计】167校园失物招领微信小程序

🙊作者简介:拥有多年开发工作经验,分享技术代码帮助学生学习,独立完成自己的项目或者毕业设计。 代码可以私聊博主获取。🌹赠送计算机毕业设计600个选题excel文件,帮助大学选题。赠送开题报告模板&#xff…

办公人导航-上网导航,找网站,下软件,找资源!

办公人导航是一个专门为办公人员设计的实用导航网站,旨在帮助用户高效地找到各种优质的办公资源和工具。无论是需要查找办公软件、学习资源还是娱乐工具,在办公人导航上都能找到你需要的内容。 办公人导航-实用的办公生活导航网站!https://ww…

PADS系列:如何导入元件库新建元件

对于普通的原理图,位置的摆放是比较随意的,并且也没有一些特殊的或者元件库里面没有的元件,相对来说绘制会比较简单。但是如果碰上复杂一点的电路,要绘制起来就会比较麻烦,需要一些新的PADS使用技巧,最基础…

详解HTTP:HTTP/1.1哪些可以优化

随着互联网的发展和应用的不断丰富,HTTP(超文本传输协议)作为网络通信的核心协议,承载着越来越重的流量和复杂的交互任务。虽然HTTP/1.1已经在很长一段时间内支撑着互联网的繁荣,但它本身也存在一些性能上的瓶颈和不足…

python format变量里有大括号报错

aa"{\"0\":{\"name\":\"0\",\"all\":{}}}".format(aa)本来想给all赋值为aa 报错 >>> aa"{\"0\":{\"name\":\"0\",\"all\":{}}}".format(aa) Traceback (most …

k8s设置pod资源请求和限制

设置资源请求和限制 实验目标: 学习如何为 Pod 设置资源请求和限制,以优化集群资源分配。 实验步骤: 创建一个 Deployment,并设置 CPU 和内存的资源请求和限制。使用 kubectl describe 命令查看资源分配情况。观察资源限制对 P…

全球首个数字人开源了

DUIX(Dialogue User Interface System)是硅基智能打造的AI数字人智能交互平台。通过将数字人交互能力开源,开发者可自行接入多方大模型、语音识别(ASR)、语音合成(TTS)能力,实现数字…

JAVA8--Stream了解

1. Stream概述 Java8中有两大最为重要的特性。 1)Lambda 表达式,前面文章已经介绍过了 2)Stream API (java.util.stream.*包下) 说到Stream便容易想到I/O Stream,而实际上我们这里讲的Stream它是Java8中对数据处理的一种抽象描述; 我们可…

apscheduler任务编排

一、形式一:A任务完成后添加B任务 from apscheduler.schedulers.background import BackgroundScheduler from datetime import datetime, timedelta# 定义任务A def task_A():print("任务A开始执行:", datetime.now())# 模拟一些耗时操作# ...print(&q…

Chrome Tracing flow event demo

Chrome Tracing flow event demo 1.效果2.解释3.代码 Chrome Tracing flow event demo 1.效果 2.解释 cpu_op 为host上的opkernel 为device上的kernel标记一条线 {"ph": "s", "id": 13, "pid": 1, "tid": 100, "ts&qu…

【Containerd】Containerd接入Harbor仓库

说明 在日常使用容器时,安全方便起见一般都会使用到私有仓库,一般都是采用 harbor 作为私有仓库,docker 对接 harbor 仓库非常简单,那么 containerd 如何对接 harbor 呢? 在内网使用 harbor 根据个人习惯&#xff0c…

【MySQL】触发器

USE stumanbd;/*向t_studentb表中插入一条记录,测试insert触发器“st_insert”是否会被触发。*/ DELIMITER $$ CREATE TRIGGER st_insert AFTER/*BEFORE*/ INSERT/*UPDATE DELETE*/ ON t_students FOR EACH ROW BEGIN SET student"插入记录成功"; END $$ …