山东大学项目实训(十四)—— 网络请求封装补充

前言

在此之前,笔者写过一篇网络请求封装的博客,但是那时候写的是封装成果,而非封装经过,因此在这篇博客上进行封装经过的补充介绍。

uni.request 的使用

在最开始,笔者不太习惯看 UNI-APP 官方文档或者说是很少有独立去看官方文档的习惯!笔者也不太懂微信小程序怎么向服务器发起网络请求。
当时好像在百度上输入了关键字 “uni-app怎么向服务器发起请求”,然后看了一大堆文档,最终都是指向uni.request。
然后就搜起了uni.request,最后发现原来UNI-APP官方文档里面有这 API !并且有详细的使用说明!
在这里插入图片描述
但是笔者作为一名几乎很少独立去看官方文档的人,是挺难看多这些字段啊什么表达的是什么意思,具体怎么使用的虽然文档下面有代码样例,但是笔者也不太会使用!

这里读者可能会问:连官方文档都不会看,那你是怎么学习后端知识的?
答:B站大学YYDS,里面的讲师说过很多次:“虽然现在的技术有我给你们带路,带你们看源码,带你们看文档。但是以后假如又有新技术出现了呢?这就得自己去看官方文档,自己去琢磨和学习了,所以大家最好是培养这样的学习习惯。” 所以有人带路,和自己亲身经历是截然不同的效果。

最终还是慢慢的读懂了官方文档,并成功向自己开的本地8080端口发起了网络请求。

在这里插入图片描述

网络请求封装

为什么要对网络请求进行封装呢?
答:笔者当时觉得每次都写一大堆重复请求代码,是十分繁琐且没有必要的,所以决定对网络请求进行封装。

前端知识的补充学习

当然,以笔者当时的水平必然是不会对网络请求进行封装的,因此就在CSDN上搜到了大量类似网络请求封装。这一搜不要紧,主要是他们的封装内容,有好多关键字是笔者看不懂的,比如箭头函数、回调函数、async、await和promise等等。

所以笔者当时十分痛苦!!基本上就是被无限套娃 —— 做一个功能的时候,发现“这个”不会,然后就去学习“这个”,但是学习过程中又悲剧的发现“这个”里面还有“那个”不会。。。依次直到触底。。

论 async、await 、Promise 之间的关系

学习总结:异步编程的最高境界就是不关心它是否是异步。async、await很好的解决了这一点,将异步强行转换为同步处理。
async/await与promise不存在谁代替谁的说法,因为async/await是寄生于Promise,Generater的语法糖。
故在理解了这一层后,就很容易对 uni.request 进行封装了。

请求封装设计思路

在这里插入图片描述

实现方案

笔者结合上面那篇文章,进行了请求封装,很显然 uni.request() 括号内的参数为一个配置对象,内含url、method等等,因此笔者对这个配置对象进行了抽离。

config: {
    
    
	// baseUrl: "http://localhost:8088/",
	header: {
    
    
		 "Content-Type":"application/json"  
	},
	data: {
    
    },
	method: "GET",
	/* 如设为json,会对返回的数据做一次 JSON.parse */
	dataType: "json",		
	responseType: "text",
	success() {
    
    },
	fail() {
    
    },
	complete() {
    
    }
},

抽离之后,需要将这些配置从外部传递进来, 结合别人的封装方法,笔者因此创建一个 request(options) 方法,返回的是 Promise 对象,并且将对应的参数传递到对应的字段上。

request(options) {
    
    
	if (!options) {
    
    
		options = {
    
    }
	}
	options.baseUrl = options.baseUrl || this.config.baseUrl
	options.dataType = options.dataType || this.config.dataType
	options.url = options.baseUrl + options.url
	options.data = options.data || {
    
    }
	options.method = options.method || this.config.method
	
	return new Promise((resolve, reject) => {
    
    
		let _config = null

		options.complete = (response) => {
    
    
			let statusCode = response.statusCode
			response.config = _config
			
			if (statusCode === 200) {
    
     //成功
				resolve(response);
			} else {
    
    
				uni.showToast({
    
    
					title: '服务器异常',
					icon: 'error',
					duration: 2000,
					mask: true
				})
				reject(response)
			}
		}

		_config = Object.assign({
    
    }, this.config, options)
		_config.requestId = new Date().getTime()
		// 向服务器发起异步请求
		uni.request(_config);
	});
},

拦截器封装

上面请求封装已经完成,但是笔者是个懒*。并不想在每个请求后面,都自己写上逻辑判断进行拦截 —— 虽然笔者刚开始有上面那种想法。。因为笔者当时不太懂请求和响应拦截器。虽然 UNI-APP 官方文档中有相应的拦截器 API,但是笔者不会用。。
在这里插入图片描述
通过翻阅相关文章,笔者在Dcloud插件市场中找到相应的拦截器封装方法,故直接在项目中使用。并且有效

interceptor: {
    
    
	request: (config) => {
    
    
		config.header = {
    
    
			"token": uni.getStorageSync("token")
		}
	},
	response: (response) => {
    
    
		// 设置请求结束后拦截器
		if (response.data.code === 200) {
    
    
			console.log('响应拦截', response)
		} else if (response.data.code === 507) {
    
    
			uni.showToast({
    
    
				title: response.data.msg,
				icon: 'none',
				duration: 2000,
				mask: true
			})
		} else {
    
    
			uni.showToast({
    
    
				title: response.data.msg,
				icon: 'none',
				duration: 2000,
				mask: true
			})
		}
	}					
},

request(options) {
    
    
	if (!options) {
    
    
		options = {
    
    }
	}
	options.baseUrl = options.baseUrl || this.config.baseUrl
	options.dataType = options.dataType || this.config.dataType
	options.url = options.baseUrl + options.url
	options.data = options.data || {
    
    }
	options.method = options.method || this.config.method

	return new Promise((resolve, reject) => {
    
    
		let _config = null

		options.complete = (response) => {
    
    
			let statusCode = response.statusCode
			response.config = _config
			
			if (this.interceptor.response) {
    
    
				let newResponse = this.interceptor.response(response)
				if (newResponse) {
    
    
					response = newResponse
				}
			}	

			if (statusCode === 200) {
    
     //成功
				resolve(response);
			} else {
    
    
				uni.showToast({
    
    
					title: '服务器异常',
					icon: 'error',
					duration: 2000,
					mask: true
				})
				reject(response)
			}
		}

		_config = Object.assign({
    
    }, this.config, options)
		_config.requestId = new Date().getTime()

		if (this.interceptor.request) {
    
    
			this.interceptor.request(_config)
		}
		uni.request(_config);
	});
},

猜你喜欢

转载自blog.csdn.net/long99920/article/details/124182627