這些天團隊里開始做小程序開發(fā)了暴拄,之前沒做過,都是第一次编饺,第一次的感覺大家都懂的乖篷。周末看了一下小程序項目的代碼,在網(wǎng)絡請求上發(fā)現(xiàn)了一些小問題透且,最終沒忍住想了點辦法把request封裝了一下撕蔼。下面來看看吧。
看項目代碼時發(fā)現(xiàn)了下面幾點問題:
- 網(wǎng)絡請求都寫在Page里秽誊,每個請求都要重復的寫wx.request以及一些基礎配置鲸沮;
- 每個頁面里都要處理相同類型的異常;
- 后端返的http status code為200以外時养距,并不能直接進入fail對應函數(shù)進行處理诉探;
針對這些問題,首先在項目目錄里新建了一個apis的目錄棍厌,把所有與API請求的東西都放在這個目錄里肾胯,如下圖這樣竖席。
1. 新建一個request類,對wx.request進行簡單封裝
在request類里做了以下幾件事:
- 在構(gòu)造函數(shù)里創(chuàng)建默認請求的http header敬肚,可以在header里配制一些內(nèi)容毕荐,在對應請求方法中如果沒有設置header參數(shù),就使用此默認header參數(shù)艳馒;
- 以get post delete put等方法對request進行封裝憎亚,在發(fā)起網(wǎng)絡請求不需要重復的寫wx.request({method:xxx})這些代碼,只要調(diào)用getRequest弄慰、postRequest等方法就可以了第美;
- 在rquest的結(jié)果返回處理函數(shù)success中,判定服務端返回的狀態(tài)代碼陆爽,對于200狀態(tài)代碼的按業(yè)務處理成功處理什往,對于非200的狀態(tài)碼按異常處理。
- 預留統(tǒng)一異常處理函數(shù)處理接口慌闭,可以通過setErrorHandler來設置統(tǒng)一的異常處理别威,這樣對于一些可以統(tǒng)一處理的異常就不用在業(yè)務頁面里去重復處理了,例如后端返回401的代碼驴剔,就可以統(tǒng)一轉(zhuǎn)到登錄頁面讓用戶登錄了省古;
- 此request不限定服務提供都,可以是自己開發(fā)的業(yè)務服務端丧失,也可以用于第三方服務的調(diào)用豺妓;
/**
* name: api.js
* description: request處理基礎類
* author: 徐磊
* date: 2018-5-19
*/
class request {
constructor() {
this._header = {}
}
/**
* 設置統(tǒng)一的異常處理
*/
setErrorHandler(handler) {
this._errorHandler = handler;
}
/**
* GET類型的網(wǎng)絡請求
*/
getRequest(url, data, header = this._header) {
return this.requestAll(url, data, header, 'GET')
}
/**
* DELETE類型的網(wǎng)絡請求
*/
deleteRequest(url, data, header = this._header) {
return this.requestAll(url, data, header, 'DELETE')
}
/**
* PUT類型的網(wǎng)絡請求
*/
putRequest(url, data, header = this._header) {
return this.requestAll(url, data, header, 'PUT')
}
/**
* POST類型的網(wǎng)絡請求
*/
postRequest(url, data, header = this._header) {
return this.requestAll(url, data, header, 'POST')
}
/**
* 網(wǎng)絡請求
*/
requestAll(url, data, header, method) {
return new Promise((resolve, reject) => {
wx.request({
url: url,
data: data,
header: header,
method: method,
success: (res => {
if (res.statusCode === 200) {
//200: 服務端業(yè)務處理正常結(jié)束
resolve(res)
} else {
//其它錯誤,提示用戶錯誤信息
if (this._errorHandler != null) {
//如果有統(tǒng)一的異常處理利花,就先調(diào)用統(tǒng)一異常處理函數(shù)對異常進行處理
this._errorHandler(res)
}
reject(res)
}
}),
fail: (res => {
if (this._errorHandler != null) {
this._errorHandler(res)
}
reject(res)
})
})
})
}
}
export default request
2. 新建一個agriknow類
在agriknow里面做了以下幾件事:
- 實現(xiàn)所有業(yè)務服務調(diào)用科侈,如查詢所有新聞列表【getNews】,查詢所有課程列表【getCourseList】炒事;
- 實現(xiàn)統(tǒng)一的異常處理臀栈,并傳給request;
- 將服務端返回的結(jié)果response轉(zhuǎn)成response.data回傳給API調(diào)用的地方挠乳;
/**
* name: agriknow.js
* description: 農(nóng)知匯服務器提供的服務
* author: 徐磊
* date: 2018-5-19
*/
import request from './request.js'
class agriknow {
constructor() {
this._baseUrl = 'https://apis.xxx.xxx.com/dev/apis/train/v1/'
this._defaultHeader = { 'Content-Type': 'application/json' }
this._request = new request
this._request.setErrorHandler(this.errorHander)
}
/**
* 統(tǒng)一的異常處理方法
*/
errorHander(res) {
console.error(res)
}
/**
* 查詢所有新聞列表
*/
getNews(page = 1, size = 10) {
let data = { page: page, size: size }
return this._request.getRequest(this._baseUrl + 'news/client', data).then(res => res.data)
}
/**
* 獲取所有課程
*/
getCourseList(page = 1, size = 10, key = null) {
let data = key != null ? { page: page, size: size, queryValue: key } : { page: page, size: size }
return this._request.getRequest(this._baseUrl + '/course/mobile', data).then(res => res.data)
}
}
export default agriknow
3. 函數(shù)的調(diào)用
- 在app中引用argriknow
import agriknow from './apis/agriknow.js' App({ onLaunch: function () { // 展示本地存儲能力 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) …… ……
- 定義一個類型為agriknow的屬性并實例化
import agriknow from './apis/agriknow.js' App({ onLaunch: function () { // 展示本地存儲能力 var logs = wx.getStorageSync('logs') || [] logs.unshift(Date.now()) wx.setStorageSync('logs', logs) …… …… }, agriknow:new agriknow() })
- 在Page里調(diào)用
const app = getApp(); Page({ data: { courseData: [], page: 1, size: 10, total: 0 }, onLoad: function () { …… …… wx.startPullDownRefresh() this.getdataList(); }, //查詢課程列表 getdataList() { app.agriknow.getCourseList(this.data.page++, this.data.size, '') .then(res => { wx.stopPullDownRefresh() let list = this.data.page > 2 ? this.data.courseData.concat(res.list) : res.list this.setData({ courseData: list }) }) .catch(res => { wx.stopPullDownRefresh() wx.showToast({ title: '出錯了权薯!', icon: 'none' }) }) }, //下拉刷新 onPullDownRefresh() { console.log("下拉刷新"); this.getdataList(); }, …… …… })
所有的東西大概就是這個樣子了,就這么個意思睡扬,希望對大家有點用盟蚣。