微信小程序和服務器端的數據交互是通過wx.request()這個API函數來完成的,這是一個異步函數。
在有些情況下,我們需要根據服務器傳遞回來的值來做下一個操作的時候,其代碼都要寫到success:function(res){ }函數中。
如果success:function(res){ } 中又要調用wx.request(),就會碰到所謂的“回調地獄”,難以編碼和維護。
wx.request()還不支持Promise這種方式,也就是說不能用wx.request().then()的方式來處理數據,所以我們需要用Promise對wx.request()來做封裝。
使用Promise分兩步:
一 、先構造 Promise 對象,語法如下,Promise的構造函數用匿名函數 function(resolve, reject){ } 做參數,
匿名函數的 resolve 和 reject 參數是執行成功和失敗時要調用的函數:
let pro = new Promise(function(resolve, reject) { //do something. });
二、然后在then方法中傳入要回調的函數做下一步的處理,如下:
pro.then(resolve, reject);
將其應用到wx.request()上,即
let baseOptions = (params, method = 'GET')=>{ let { url, data } = params let contentType = 'application/x-www-form-urlencoded' contentType = params.contentType || contentType let pro = new Promise(function(resolve, reject) { wx.request({ isShowLoading: true, loadingText: '正在加載', url: base + url, data: data, method: method, header: { 'content-type': contentType, 'Authorization': wx.getStorageSync('token') }, success(res) { if (res.statusCode === HTTP_STATUS.NOT_FOUND) { reject('請求資源不存在') } else if (res.statusCode === HTTP_STATUS.BAD_GATEWAY) { reject('服務端出現了問題') } else if (res.statusCode === HTTP_STATUS.FORBIDDEN) { reject('沒有權限訪問') } else if (res.statusCode === HTTP_STATUS.SUCCESS) { if (res.data.code === HTTP_STATUS.TOKEN_EXPIRE) { wx.clearStorageSync() wx.reLaunch({ url:'/pages/index/index' }) wx.showToast({ title: '登錄狀態過期,請重新登錄', icon:'none', duration: 2000 }) }else if(res.data.code === HTTP_STATUS.AUTHENTICATE){ wx.clearStorageSync() wx.reLaunch({ url:'/pages/index/index' }) wx.showToast({ title: '認證失敗,請重新登錄', icon:'none', duration: 2000 }) } else { if(res.header.Authorization){ wx.setStorageSync('token',res.header.Authorization) } resolve(res.data) } } }, fail(error) { console.error(error) if(error.errMsg === 'request:fail timeout'){ error.errMsg = '請求超時' } }, error(e) { console.error('api', '請求接口出現問題', e) } }) }) return pro } export let get = (url, data = '')=>{ let option = { url, data } return baseOptions(option) } export let post = function (url, data, contentType) { let params = { url, data, contentType } return baseOptions(params, 'POST') }
調用代碼為:
getUserInfoByOpenId() { const openId = wx.getStorageSync('openid') get('/sysuser/getUserInfoByOpenId',{openId:openId}).then( res => { if(res.code === 200){ this.setData({ userInfo: res.data }) }else { wx.showToast({ title: res.message, icon: 'none', duration: 2000 }) } } ).catch((e) => { wx.showToast({ title: e.errMsg, icon: 'none', duration: 2000 }) }) }
即相當於可使用wx.request().then()了。
