uniapp请求接口封装

uniapp请求接口封装

uniapp发送请求跟web的不同,而且通过uni.request这个方法进行调用。

示例:

uni.request({url: 'https://www.example.com/request', //仅为示例,并非真实接口地址。data: {text: 'uni.request'},header: {'custom-header': 'hello' //自定义请求头信息},success: (res) => {console.log(res.data);this.text = 'request success';}
});

可能对于习惯了使用axios的开发者而言,会不太喜欢使用这种方式。因此文章讲介绍一下怎么在uniapp上实现一个类似axios的请求方式。

定义构造函数

在这里命名为UniAxios

class UniAxios {constructor(options = {}) {this.defaults = options;this.interceptors = {request: new InterceptorManager(),response: new InterceptorManager(),};}
}

UniAxios构造函数里创建了两个拦截器管理实例。

同时添加了拦截器处理

拦截器

拦截器管理机制其实很简单。就只有一个handlers属性(用于保存拦截器)及三个原型方法(添加、移除、执行)

class InterceptorManager {constructor() {this.handlers = [];}
}InterceptorManager.prototype.use = function use(fulfilled, rejected, options) {this.handlers.push({fulfilled: fulfilled,rejected: rejected,// 默认异步synchronous: options ? options.synchronous : false});// 当前拦截器idreturn this.handlers.length - 1;
};InterceptorManager.prototype.remove = function remove(id) {if (this.handlers[id]) {// 只移除拦截器引用,不处理数组,否则会影响之前的拦截器索引this.handlers[id] = null;}
};InterceptorManager.prototype.forEach = function forEach(fn) {this.handlers.forEach((handler) => {if (handler !== null) {fn(handler);}});
};

处理不同平台请求method

对于不同平台,可能支持的method不一致,因此这里也需要进行处理。

因为不同的请求方式在uni.request中只是method字段的不同,完全可以单独把uni.request封装好,通过传递method来实现不同的请求方法。

以微信小程序为例:

// 微信小程序支持的请求方法
const supportedMethodType = ['GET','POST','PUT','DELETE','CONNECT','HEAD','OPTIONS','TRACE',
];// 通过遍历的方式添加到构造函数的原型上
supportedMethodType.forEach((item) => {LeoAxios.prototype[item.toLocaleLowerCase()] = function(url, data, header, ...args) {return this.request(item.toLocaleLowerCase(),url,data, {...this.defaults.header,...header,},...args);};
});

上面添加的这些原型方法内部其实都是调用了同一个request方法。

请求发送

request方法中,需要合并上面的不同请求传过来的参数以及初始化UniAxios时的配置。

同时处理拦截器,将拦截器组装成一个数组用于Promise.then的链式调用。

function processArguments(args) {if (args.length > 1) {return {method: args[0],url: args[1],data: args[2],header: args[3],rest: args.length > 4 ? args.slice(3) : undefined,};}return args;
}function mergeConfig(defaults, config) {return Object.assign(defaults, config);
}LeoAxios.prototype.request = function request() {let config = {};// 兼容传参config = processArguments(arguments);// 合并配置config = mergeConfig(JSON.parse(JSON.stringify(this.defaults)), config);// 请求拦截器栈const requestInterceptorChain = [];// 拦截器是否是同步的let synchronousRequestInterceptors = true;this.interceptors.request.forEach(function unshiftRequestInterceptors(interceptor) {synchronousRequestInterceptors =synchronousRequestInterceptors && interceptor.synchronous;// 将处理方法推进栈中,采用unshift方法requestInterceptorChain.unshift(interceptor.fulfilled,interceptor.rejected);});// 响应拦截器栈const responseInterceptorChain = [];this.interceptors.response.forEach(function pushResponseInterceptors(interceptor) {responseInterceptorChain.push(interceptor.fulfilled, interceptor.rejected);});let promise;// 异步的处理if (!synchronousRequestInterceptors) {// 请求方法let chain = [dispatchEvent, undefined];// 在请求方法前添加请求拦截器Array.prototype.unshift.apply(chain, requestInterceptorChain);// 在请求方法后添加响应拦截器chain = chain.concat(responseInterceptorChain);promise = Promise.resolve(config);while (chain.length) {promise = promise.then(chain.shift(), chain.shift());}return promise;}// 请求拦截器while (requestInterceptorChain.length) {const onFulfilled = requestInterceptorChain.shift();const onRejected = requestInterceptorChain.shift();try {newConfig = onFulfilled(config);} catch (err) {onRejected(err);break;}}// 发送请求try {promise = dispatchEvent(config);} catch (err) {return Promise.reject(err);}while (responseInterceptorChain.length) {promise = promise.then(responseInterceptorChain.shift(),responseInterceptorChain.shift());}return promise;
};

dispatchEvent方法就是用于发送请求。

function dispatchEvent(config) {let timer,requestTask,// overtime 请求是否超时overtime = false;// timer 检测超时定时器,requestTask 网络请求 task 对象,aborted 请求是否已被取消,abort 取消请求方法return new Promise((resolve, reject) => {if (config.cancel) {return reject({requestConfig: config,errMsg: '网络请求失败:主动取消'});}requestTask = uni.request({url: config.url[0] === '/' ? config.baseUrl + config.url : url,data: config.data,method: config.method,header: config.header,...config.rest,success: async function success(res) {res.requestConfig = config;if(config.statusCode && config.statusCode.indexOf(res.statusCode) === -1) {reject(res);} else {resolve(res);}},fail: async function fail(err) {if (overtime) {return;}reject({...err,requestConfig: config});},complete: function complete() {// 清除超时定时器clearTimeout(timer);},});timer = setTimeout(async () => {// 会触发fail方法overtime = true;requestTask.abort();reject({requestConfig: config,errMsg: '网络请求时间超时'});}, config.timeout);})
}

在这个方法中还添加了超时处理,在超时后调用requestTask.abort方法。

使用

来看看具体怎么使用:

首先初始化一个实例:

const request = new LeoAxios({baseUrl: 'http://localhost:8081/',timeout: 60000,header: {'Content-Type': 'application/json',},statusCode: [200, 304, 401]
});

传入一些基础配置。

之后就可以使用request.postrequest.get这些方法了。

request.get('/test', {}, {"Content-Type": 'application/x-www-form-urlencoded'
});request.post('/testpost', {key: 1, value: 2});

拦截器的使用

拦截器有几点需要注意的是:

  • fulfilled方法中需要返回传入的参数,保证下一个拦截器中能获取到传参
  • rejected方法中需要返回一个Promise.reject,这样才能保证在其他拦截器触发的都是rejected
request.interceptors.request.use(function fulfilled(options) {return options;},function rejected(err) {return Promise.reject(err);},option: {synchronous: false}
);

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

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

相关文章

【云原生】k8s安全机制

前言 Kubernetes 作为一个分布式集群的管理工具,保证集群的安全性是其一个重要的任务。API Server 是集群内部各个组件通信的中介, 也是外部控制的入口。所以 Kubernetes 的安全机制基本就是围绕保护 API Server 来设计的。 比如 kubectl 如果想向 API…

机器学习/深度学习常见算法实现(秋招版)

包括BN层、卷积层、池化层、交叉熵、随机梯度下降法、非极大抑制、k均值聚类等秋招常见的代码实现。 1. BN层 import numpy as npdef batch_norm(outputs, gamma, beta, epsilon1e-6, momentum0.9, running_mean0, running_var1)::param outputs: [B, L]:param gamma: mean:p…

工欲善其事,必先利其器之—react-native-debugger调试react native应用

调试react应用通常利用chrome的inspector的功能和两个最常用的扩展 1、React Developer Tools (主要用于debug组件结构) 2、Redux DevTools (主要用于debug redux store的数据) 对于react native应用,我们一般就使用react-nativ…

Vue动态多级表头+行列合计+可编辑表格

新建组件&#xff1a;Table.vue <template><el-table-column :label"coloumnHeader.label" :prop"coloumnHeader.label"><template v-for"item in coloumnHeader.children"><tableColumnv-if"item.children &&am…

Java项目查询统计表中各状态数量

框架&#xff1a;SpringBoot&#xff0c;Mybatis&#xff1b;数据库&#xff1a;MySQL 表中设计2个状态字段&#xff0c;每个字段有3种状态&#xff0c;统计这6个状态各自的数量 sql查询语句及结果如图 SQL&#xff1a; SELECT SUM(CASE WHEN A0 THEN 1 ELSE 0 END) AS A0…

数据分析的iloc和loc功能

大家好&#xff0c;在处理大型数据集时&#xff0c;使用有效的数据操作和提取技术是必要的。Pandas数据分析库提供了强大的工具&#xff0c;用于处理结构化数据&#xff0c;包括使用iloc和loc函数访问和修改DataFrame元素的能力。在本文中&#xff0c;我们将探讨iloc和loc之间的…

Java 【dubbo rpc改feign调用】解决调用服务提供方无法传递完整参数问题

dubbo rpc改feign调用&#xff0c;feign调用接口异常统一处理 服务调用方服务提供方 【框架改造问题点记录&#xff0c;dubbo改为spring cloud alibaba】 【第二篇】feign接口异常解决 【描述】多参数情况下&#xff0c;调用服务提供方无法传递完整参数、改SpringQueryMap原因是…

论文笔记--OpenPrompt: An Open-source Framework for Prompt-learning

论文笔记--OpenPrompt: An Open-source Framework for Prompt-learning 1. 文章简介2. 文章概括3 文章重点技术4. 文章亮点5. 原文传送门 1. 文章简介 标题&#xff1a;OpenPrompt: An Open-source Framework for Prompt-learning作者&#xff1a;Ning Ding, Shengding Hu, We…

短视频seo矩阵系统源码开发部署

目录 短视频矩阵源码部署步骤简单易懂&#xff0c;开发者只需按照以下几个步骤进行操作&#xff1a; 代码展示---seo关键词分析 开发要点&#xff1a; 代码展示如下&#xff1a; 开发部署注意事项&#xff1a; 说明&#xff1a;本开发文档适用于短视频seo矩阵系统源码开发…

django中批量添加对象SupplierNature.objects.bulk_create(SupplierNature对象)

insert_list [] for i in range(10000):namef"{i} "insert_list.append(MyModel(namename)) MyModel.objects.bulk_create(insert_list)注明&#xff1a;创建的是对象

PostgreSQL考试难不难 ?

当涉及到PostgreSQL考试的详细难度&#xff0c;以下是一些可能涉及的主题和考点&#xff0c;这些主题在不同的考试中可能有所不同&#xff1a; 1.数据库基础知识&#xff1a;数据库的基本概念、关系型数据库模型、表、字段、主键、外键等。 2.SQL语言&#xff1a;对SQL语言的掌…

ACME申请SSL证书

1.开放443端口 firewall-cmd --permanent --add-port443/tcp # 开放443端口 firewall-cmd --reload # 重启防火墙(修改配置后要重启防火墙)2.安装ACME # 安装acme curl https://get.acme.sh | sh -s email你的邮箱地址 # 别名 alias acme.sh~/.acme.sh/acme.sh3.使用ACME申请…

攻防世界-web-easytornado

题目描述&#xff1a;Tornado 框架。打开链接是一个简单的界面 1. 思路分析 看到有个/flag.txt&#xff0c;我们点击进去看下 发现传入了两个参数&#xff0c;一个是filename&#xff0c;还有一个是filehash 看到里面的内容&#xff0c;提示我们真正的flag在 /flllllllllllla…

Django auto_now=True 不更新

create_time models.DateTimeField(db_column"CreateTime", auto_now_addTrue) update_time models.DateTimeField(db_column"UpdateTime", auto_nowTrue) 现象&#xff1a; update_time 的auto_now设置为True&#xff0c;更新了表格里的某个属性的值&…

【LeetCode 算法】Walking Robot Simulation 模拟行走机器人 - 二分

文章目录 Walking Robot Simulation 模拟行走机器人问题描述&#xff1a;分析代码二分 Tag Walking Robot Simulation 模拟行走机器人 问题描述&#xff1a; 机器人在一个无限大小的 XY 网格平面上行走&#xff0c;从点 (0, 0) 处开始出发&#xff0c;面向北方。该机器人可以…

【自监督预训练 2023】MCL

【自监督预训练 2023】MCL 论文题目&#xff1a;Multi-Level Contrastive Learning for Dense Prediction Task 中文题目&#xff1a;稠密预测任务的多级对比学习 论文链接&#xff1a;https://arxiv.org/abs/2304.02010 论文代码&#xff1a;https://github.com/GuoQiushan/MC…

Unity视角拉近时物体缺失的问题处理

在Unity的开发过程中&#xff0c;我们可能会遇到以下情况&#xff1a; 就是在场景的不断编辑中&#xff0c;突然又一次打开场景&#xff0c;再拉近或拉远场景视角时&#xff0c;会出现场景中的对象会显示不全的问题。 出现了这样的情况会让场景的预览很不友好。 出现这个问题的…

rust

文章目录 rustCargoCreating a rust project How to Debug Rust Programs using VSCodebasic debuggingHow to pass arguments in Rust debugging with VS Code. References rust Cargo Cargo is a package management tool used for downloading, compiling, updating, and …

行为型模式 - 命令模式

概述 日常生活中&#xff0c;我们出去吃饭都会遇到下面的场景。 定义&#xff1a; 将一个请求封装为一个对象&#xff0c;使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通&#xff0c;这样方便将命令对象进行存储、传递、调用、增加与管理。 结构 …

Hugging News #0717: 开源大模型榜单更新、音频 Transformers 课程完成发布!

每一周&#xff0c;我们的同事都会向社区的成员们发布一些关于 Hugging Face 相关的更新&#xff0c;包括我们的产品和平台更新、社区活动、学习资源和内容更新、开源库和模型更新等&#xff0c;我们将其称之为「Hugging News」。本期 Hugging News 有哪些有趣的消息&#xff0…