此方法是異步請求封裝成同步請求,加上token驗證,環境試用微信小程序,能夠修改文件中的ajax,進行封裝本身的,好比用axios等ios
成功碼採用標準的 200 到 300 和304 ,須要能夠自行修改ajax
同步任務接入以後,每一個任務會進行token的驗證,每一個任務之間都是同步請求,包括tokenjson
/** * 同步流請求 * token驗證每一個接口 * 柯里化添加同步任務 * resolve返回res,cb * reject 返回res,cb * 經過任務中斷測試 * 經過成功失敗回調函數測試 * * 任務流 任務接入柯里化函數 currying(()=>{}) --> * 開始執行 currying() 進入g函數循環同步執行異步方法 --> * 執行異步方法 調用 rp 函數 封裝 return new promise --> * rp 函數 執行判斷 token 狀態 進行處理 */ const regeneratorRuntime = require('./regenerator-runtime/runtime.js') //runtime類 const errorMessage = '服務繁忙,稍後再試' //公共提示 const successMessage = '完成' //公共提示 class SuperClass { constructor() { Object.assign(this, {}) //等待執行的接口 this.wait = [] } //Promise 請求接口 rp(opts, skipToken = false) { const _t = this, data = opts.data || {} //小程序標識 data.source = opts.sourceFlag ? data.source : 1; //請求信息 console.group(`請求接口---${opts.url}`); console.log('接口信息', { opts, skipToken }) console.groupEnd(); return new Promise(function(resolve, reject) { opts.header = { "Content-Type": "application/json;charset=utf-8", //不須要走token的接口 Authorization: !!opts.skipToken ? '' : (wx.getStorageSync('token') || '') } wx.request({ url: '域名' + opts.url, data: data, header: opts.header, method: opts.method, dataType: 'json', responseType: 'text', success: function(res) { const { data } = res //成功 400爲token失效 處理token失效問題 內層函數收集token失敗碼歸併處理 if (data && (_t.successCode({ code: data.code }) || data.code == 400)) { resolve(data) } else { //其餘不可預測爲失敗 reject(data) } }, fail: function(res) { reject(res.data) }, complete: function(res) { //完成中止加載 wx.hideToast() opts.complete && opts.complete(res.data) } }) }) } //爲空參數拋異常 paramNoNull() { throw new Error('Missing parameter') } // g函數 async g() { let _t = this, //中斷任務 isbreak = !1 for (let [i, v] of _t.wait.entries()) { const r = await v().catch((res) => { //收集 全部的錯誤 統一執行 提示 或者錯誤回調 const { cb, message } = res //同步流中斷 _t.clearWait() isbreak = !0; //沒有回調函數執行錯誤提示 'cb' in res ? cb() : (wx.factory._toast(message || errorMessage)) }) //任務執行成功 if (!!r && r.constructor === Object && !!Object.keys(r).length) { const { res: { code, data, message }, cb } = r //外層函數只處理成功狀態 if (_t.successCode({ code })) { !!cb && cb() //同步流執行完成 if ((i + 1) == _t.wait.length) { _t.clearWait() wx.factory._toast(message || successMessage) } } else { //同步流中斷 _t.clearWait() isbreak = !0 wx.factory._toast(message || errorMessage) } } if (!!isbreak) { break } } } //清空任務 clearWait() { this.wait = [] } //柯里化 currying() { const _t = this return (function(arg) { if (arg.length === 0) { _t.g() } else { [].push.apply(_t.wait, arg); } })(arguments) } //成功碼 successCode({ code = 404 }) { return (code >= 200 && code < 300) || code == 304 } } //超類,實現多繼承 const decorator = Sup => class extends Sup { constructor(...args) { super(...args) } //獲取token接口 greatetoken(opts) { let codeOPts = JSON.parse(JSON.stringify(opts)); codeOPts.url = `/getToken` codeOPts.method = `POST` codeOPts.data = { appIds: "xx", userId: 5 } return super.rp(codeOPts, true).then((res) => { const { code, data } = res if (super.successCode({ code: cb.code })) { if (!!data && !!data.token) { //全局token存儲 方式爲 storage wx.setStorageSync('token', data.token) } else { wx.factory._toast('獲取token失敗') } } else { wx.factory._toast('獲取token失敗') } }).catch(() => { wx.factory._toast('獲取token失敗') }) } /** * 接口公共類 * 同步請求返回 Promise * 請求 token 爲前提,爲空 過時從新請求 */ async send(opts) { const token = wx.getStorageSync('token'), sendFun = (opts) => { //轉化http請求 catch捕獲promise的reject 展現接口級別錯誤 只作console打印 其餘操做流入g函數(回調,提示) return super.rp(opts).catch(res => { //此處顯示rp reject 報錯 console.group(`%c請求接口---${opts.url}---報錯`, 'color:red;'); console.log(` --> 參數`, { data: opts.data }); console.log(` --> 返回值`, { res }); console.groupEnd(); //把錯誤信息傳到 g 函數的catch裏面 opts.fail && opts.fail(res) }) }, successFun = async(opts) => { const cb = await sendFun(opts) //把成功信息傳到g函數裏面 super.successCode({ code: cb.code }) && opts.success && opts.success(cb) } if (!opts.skipToken) { //須要token請求 if (!token) { //token爲空 直接發起token請求 await this.greatetoken(opts) await successFun(opts) } else { const cb = await sendFun(opts) if (!!cb) { //400 token過時 只有在存在token的狀況下才會有時效的狀況 歸併處理 if (cb.code == 400) { await this.greatetoken(opts) await successFun(opts) } else { //把成功信息傳到g函數裏面 super.successCode({ code: cb.code }) && opts.success && opts.success(cb) } } } } else { await successFun(opts) } } post(opts) { opts.method = "POST"; this.send(opts) } get(opts) { opts.method = "GET"; this.send(opts); } } class Http extends decorator(SuperClass) { //子類 constructor() { //繼承參數 super() } } export default new Http
引入方式,全局調用axios
import Http from './public/js/request'
wx.http = Http
調用執行,可用bind函數進行傳參小程序
success返回爲成功的,code值流入任務進行code值判斷區分 resolve微信小程序
fail返回失敗 rejectpromise
complete執行的爲方法微信
Page({ onLoad(){ wx.http.currying(this.a.bind(this, { a: 1 })) //進行傳參bind wx.http.currying(this.b) wx.http.currying() }, a() { const _t = this wx.factory._toast('加載a信息中...', 6000) return new Promise((resolve, reject) => { wx.http.post({ url: 'a', data: { "params": { id:33 } }, success(res) { resolve({ res,
cb()=>{} }) }, fail(res) { reject({ res,
cb()=>{} }) } }) }) }, b() { const _t = this wx.factory._toast('加載b信息中...', 6000) return new Promise((resolve, reject) => { wx.http.post({ url: 'b', data: { id:33 }, success(res) { resolve({ res }) }, fail(res) { reject({ res }) } }) }) } })