【小程序】请求与封装
微信小程序进行网络通信,只能和指定的域名进行通信,微信小程序包括四种类型的网络请求。
请求 | 方法 |
---|---|
普通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使用 、 节点操作 、 页面跳转 、 缓存
----------------------------------------