【小程序】請求與封裝


【原文:請求與封裝】

微信小程序進行網絡通信,只能和指定的域名進行通信,微信小程序包括四種類型的網絡請求。

請求 方法
普通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使用 、 節點操作 、 頁面跳轉 、 緩存

  前端架構淺談

----------------------------------------

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM