传统的实现

最传统的接口调用一般是封装一个方法, 然后里面请求接口, 回调获取接口返回:

let $ = require('jquery')

function getData(url) {
  $.get(url, function(data, status){
    //TODO: 对接口返回处理
  })
}

进阶的实现

虽然后面出现了Promise, 但依然没有跳出回调地狱:

let axios = require('axios')
function getData(url) {
  axios.get(url).then(function(data, status){
    //TODO: 对接口返回处理
  })
}

更进阶的实现

利用 async await 解决回调地狱, 由于async await 只会在promise resolve 触发, 因此对 promise 再包装一层promise, 以获取里面一层promise触发reject 回调数据:

let axios = require('axios')
function getData(url) {
  return new Promise((resolve, reject) => {
    axios.get(url).then(function(data, status){
      //TODO: 对接口返回处理
      resolve({code:0, data: data})
    }, function(e){
      //TODO: 网络异常
      resolve({code: -1, data: data})
    })
  }
}

代码升华实现

通常, 我们对接口的请求及接口逻辑实现会封装在一个方法里面, 例如上面的getData方法. 但此处逻辑所有接口基本是一致的, 我们追求的完美就是: 用最少的代码实现最强大的功能! 不出现任何两个逻辑相同的方法.

我们来对接口层分析: 实现接口服务层, 我们需要的基本信息是: url, method, header(通常是一致的), 以及某些接口的特性信息, 比如不需要cookie等. 提取如下:

{
  url: 'xxx/xxx',
  method: 'get',
  header:{
    content-type: 'xxx'
  },
  withCredentials: true
}

通常, header, withCredentials 是一致的, 可以缺省, method可以设置为get. 接口层对上层业务逻辑层需要提供调用方法名, 于是我们的接口层应该就是这么简单:

{
  getXxxData: {
    url: 'get/xxxx'
  },
  postData: {
    url: 'post/xxx',
    method: 'post'
  }
}

业务逻辑层调用方式:

imports apis from '@/apis'
Vue.prototype.apis = apis

methods:{
  async getData() {
    let res = await this.getXxxData()
    if (res.code === 0) {
      // TODO: do somethings
    }
  }
}

apis/index.js 实现: 戳这里在线查看

完整实现(这是一个管理后台模板, 欢迎社区一起完善, 欢迎fork): https://github.com/cnvoid/blank-admin