zoukankan      html  css  js  c++  java
  • 【小程序】请求与封装

    【原文:请求与封装】

    微信小程序进行网络通信,只能和指定的域名进行通信,微信小程序包括四种类型的网络请求。

    请求方法
    普通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使用 、 节点操作 、 页面跳转 、 缓存

      前端架构浅谈

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

  • 相关阅读:
    Python 获取校内(人人网)的所有好友照片存储到本地
    Learning DNN Module Developers guide
    第一次用blog
    杂谈:淘宝商城“暴动”事件
    百度三维地图体验(坑爹啊有图有真相)
    从历史的角度杂谈《中国没有乔布斯,美国没有史玉柱》说起
    南漂一年个人随想录
    我离淘宝有多远?
    centos搭建Git分布式管理控制系统
    乔布斯与中国
  • 原文地址:https://www.cnblogs.com/lilicat/p/10515184.html
Copyright © 2011-2022 走看看