微信小程序進行網絡通信,只能和指定的域名進行通信,微信小程序包括四種類型的網絡請求。
請求 | 方法 |
---|---|
普通HTTPS請求 | wx.request |
上傳文件 | wx.uploadFile |
下載文件 | wx.downloadFile |
WebSocket通信 | wx.connectSocket |
這里主要對普通HTTPS請求做一次詳細介紹。
普通HTTPS請求
要微信小程序進行網絡通信,必須先設置域名,不然會提示不合法。設置域名的信息可以在開發者工具-詳情-域名信息中看到。
使用wx.request
可以發起一個http
請求
wx.request({
url: 'test.php', // 開發者服務器接口地址 data: { // 請求的參數 x: '', y: '' }, method: 'GET', // HTTP 請求方法, 默認GET header: { // 設置請求的 header 'content-type': 'application/json', // 默認值 'cookie': 'token=' + token }, dataType: 'json', // 返回的數據格式, 默認json responseType: 'text', // 響應的數據類型, 默認text success (res) { // 接口調用成功的回調函數 console.log(res.data) }, fail () { // 接口調用失敗的回調函數 }, complete () { // 接口調用結束的回調函數(調用成功、失敗都會執行) } })
請求封裝
但在平時項目使用中,我們往往會對HTTP請求做一層封裝。這里介紹兩種方法:1. 回調函數 2. promise
第一種 回調函數
假設項目中有一個文件為http.js
, 里面存在如下代碼
// http.js var api_base_url = 'pay.tairanmall.com' var token = 'some code as token' /** * 傳入params對象,url, data, method, failBack, successBack **/ export default function (params){ if(!params.method){ params.method = "GET" } wx.request({ url: api_base_url + params.url, method: params.method, data: params.data, header:{ 'content-type':'application/json', 'cookie': 'token=' + token }, success:function(res){ let code = res.statusCode.toString() if (code.startsWith('2')){ params.successBack && params.successBack(res.data) } else{ params.failBack && params.failBack(res.data) wx.showToast({ title: res.data.error.description, icon: 'none', duration: 2000 }) } }, fail:function(err){ // some fail code } }) }
你在api.js
文件中,引入http.js
文件,代碼如下
// api.js import http from 'http.js' function getOrderDetailData(params,successBack,failBack) { http({ method: 'POST', url: '/some/url', data: params, successBack: successBack, failBack: failBack }) } export { getOrderDetailData }
之所以不在頁面中直接引入引入http.js
,而加了一層api.js
文件,是為了項目的規范性和可維護性等方面考慮的。把所有的http請求地址集中在一個文件中,能夠更加直觀看到項目使用了哪些接口,使得后續的項目開發維護以及項目優化迭代更加容易。(舉例:接口更換)
最后在某個頁面中使用 home/home.js
// home/home.js import { getOrderDetailData } from 'api.js' Page({ /** * 頁面的初始數據 */ data: { payId: '', // 支付訂單ID orderDetail: {}, // 訂單詳情 }, /** * 頁面顯示的時候 */ onShow: function () { // 請求獲取訂單信息 this.getOrderDetail({ payId: this.data.payId}) }, /** * 獲取訂單信息 */ getOrderDetail: function (params) { let _this = this getOrderDetailData(params, function (data) { _this.setData({orderDetail: data}) }) } })
上述的代碼還是比較清晰的,但是當項目變得臃腫且業務代碼繁雜的時候,過多的回調函數常常會使得代碼難以理解和維護。 代碼中每一層的回調函數都需要依賴上一層的回調執行完,形成層層嵌套的關系,就會產生回調地域。類似如下代碼
import { getA, getB, getC, getD } from 'api.js' function callback () { getA({id: 'A'}, function (Adata) { getB({id: Adata.id}, function(Bdata){ getC({id: Bdata.id}, function(Cdata) { getD({id: Cdata.id}, function() { ... }) }) }) }) }
上述代碼無疑是不利於我們閱讀與維護的,接下來介紹使用PROMISE。
第二種 PROMISE
首先先介紹一下Promise,以下摘自阮一峰老師的《ES6入門》
它是異步編程的一種解決方案,比傳統的解決方案——回調函數和事件——更合理和更強大。 簡單說它就是一個容器,里面保存着某個未來才會結束的事件(通常是一個異步操作)的結果。從語法上說,Promise 是一個對象,從它可以獲取異步操作的消息。Promise 提供統一的 API,各種異步操作都可以用同樣的方法進行處理。 Promise對象代表一個異步操作,有三種狀態:pending(進行中)、fulfilled(已成功)和rejected(已失敗)。 有了Promise對象,就可以將異步操作以同步操作的流程表達出來,避免了層層嵌套的回調函數。此外,Promise對象提供統一的接口,使得控制異步操作更加容易。
假設項目中有一個文件為http.js
, 里面存在如下代碼
// http.js var api_base_url = 'pay.tairanmall.com' var token = 'some code as token' export default function ({url, data={},method='GET'}) { return new Promise((resolve, reject)=>{ wx.request({ url: api_base_url + url, method: method, data: data, header:{ 'content-type':'application/json', 'cookie': 'token='+token }, success:(res)=>{ const code = res.statusCode.toString() if (code.startsWith('2')){ resolve(res.data) } else{ reject(res.data) wx.showToast({ title: res.data.error.description, icon: 'none', duration: 2000 }) } }, fail:(err)=>{ } }) }) }
你在api.js
文件中,引入http.js
文件,代碼如下
// api.js import http from 'http.js' function getOrderDetailData(params) { return http({ method: 'POST', url: '/some/url', data: params }) } export { getOrderDetailData }
最后在某個頁面中使用 home/home.js
// home/home.js import { getOrderDetailData } from 'api.js' Page({ /** * 頁面的初始數據 */ data: { payId: '', // 支付訂單ID orderDetail: {}, // 訂單詳情 }, /** * 頁面顯示的時候 */ onShow: function () { // 請求獲取訂單信息 this.getOrderDetail({ payId: this.data.payId}) }, /** * 獲取訂單信息 */ getOrderDetail: function (params) { getOrderDetailData(params).then(data=> { this.setData({orderDetail: data}) }) } })
import { getA, getB, getC, getD } from 'api.js' function callback () { getA({id: 'A'}).then(Adata => { return getB({id: Adata.id}) }).then(Bdata => { return getC({id: Bdata.id}) }).then(Cdata => {s return getD({id: Cdata.id}) }).then(Ddata => { ... }) }
使用function定義的函數,this的指向隨着調用環境的變化而變化的,而箭頭函數中的this指向是固定不變的,一直指向的是定義函數的環境。
----------------------------------------
小程序系列:
基礎使用: component使用 、 wxs使用 、 節點操作 、 頁面跳轉 、 緩存
----------------------------------------