如何高效封装一个网络请求
高效封装网络请求需要考虑以下几点
1. 单例模式
class Http {
constructor(){
this.instance = ''
....
}
static getInstance(){
return this.instance || new Http()
}
}
export default Http.getInstance()
2. 封装网络请求对象
包括请求方法、请求参数、请求头、URL等信息
class Http {
constructor(){
this.instance = ''
this.config = {...}
....
}
get(options){
const {data, params } = options
const _data = data || params || {}
return this._request({
...options,
url: this.handleURL({ ...options, method: 'GET', data: _data }),
data: data || params || {},
method: 'GET',
}).then((res: IResponseData) => {
...
}).catch((err = {}) => {
...
})
}
// 处理url,拼接时间戳,get,post的参数
handleURL(options){
}
//处理公共的头部
_request(options){
const { header} = this.config
const requestTask = Request.request({
...options,
data: JSON.stringify(data)
header: {
...header,
...options.header
}
success:()=>{}
fail: ()=>{}
})
}
post(options){
...
}
static getInstance(){
return this.instance || new Http()
}
}
export default Http.getInstance()
3. 封装网络请求结果回调,
包括请求成功、请求失败、错误等结果回调方法
class Http {
constructor(){
this.instance = ''
this.config = {...}
this.hook = {
requestBefore, // 处理userkey,设置header
requestComplete, // 处理401未登录的情况,处理usekey的更新
}
....
}
get(options){
const {data, params } = options
const _data = data || params || {}
this._callHookFun('requestBefore', options)
return this._request({
...options,
url: this.handleURL({ ...options, method: 'GET', data: _data }),
data: data || params || {},
method: 'GET',
}).then((res: IResponseData) => {
this._callHookFun('requestComplete', res)
...
}).catch((err = {}) => {
this._callHookFun('requestError', err)
...
})
}
// 处理hook调用
_callHookFun(hookName: 'requestBefore' | 'requestComplete' | 'requestError' ) {
if (typeof this.hook[hookName] === 'function') {
(this.hook[hookName] as Function)(options)
}
}
// 处理url,拼接时间戳,get,post的参数
handleURL(options){
}
// 处理公共的头部,封装请求
_request(options){
const { header} = this.config
const requestTask = Request.request({
...options,
data: JSON.stringify(data)
header: {
...header,
...options.header
}
success:()=>{}
fail: ()=>{}
})
}
static getInstance(){
return this.instance || new Http()
}
}
export default Http.getInstance()
4. 网络请求的并发处理
Request.request,对上边request方法进行扩展(简化版),并发处理5条网络请求
class RequestQueue {
constructor() {
this.queue = []
this.timer = 0,
this.limitNum = 5
}
request(options) {
this.queue.push(options)
return this.run() // 需要有返回值
}
run() {
if (!this.queue.length) {
return null
}
if (this.queue.length <= this.limitNum) {
const options = this.queue.pop()
const completeFn = options.complete
options.complete = (...args) => {
completeFn && completeFn.apply(options, args)
this.run()
}
return wx.request(options)
}
static getInstance() {
return this.instance || new RequestQueue()
}
}
export default RequestQueue.getInstance()
5. 网络请求的缓存处理
cacheDate //缓存时间
async function get(options){
return cacheLoad(()=>{
....
return Http.get().then(()=>{})
})
}
// 处理缓存请求的存取
function cacheLoad(req){
。。。
}
6. 网络异常的处理
async function get(options){
return cacheLoad(()=>checkNetwork(()=>{
....
return Http.get().then(()=>{})
})
})
}
export function checkNetwork(callback, options) {
const { networkInfo = {} } = getApp().globalData
if (networkInfo === true || networkInfo.isConnected) {
return callback()
}
toast(!!options.hideToast, '网络异常,请重试')
return Promise.reject({ message: '网络异常,请重试' })
}
7. 撤销怎么设计
abortKey的设计
// 以上_request方法的扩展
_request(options,abortKey){
const { header} = this.config
const requestTask = Request.request({
...options,
data: JSON.stringify(data)
header: {
...header,
...options.header
}
success:()=>{}
fail: ()=>{}
})
abortKey && this._abortRequest(abortKey, requestTask)
}
// @params requestTask是网络请求的id
_abortRequest(abortKey: string, requestTask: any) {
if (abortKey) {
const task = this.requestTask[abortKey]
task && task.abort()
this.requestTask[abortKey] = requestTask
}
}
8. 网络请求的重试。。。