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