preface

As a front-end developer, we can’t do without the use of HTTP library in our development projects from js and jQuery to MVVM and MVC frameworks such as Vue, React and Angular.

HTTP library

1. JQuery $.ajax

The XMLHttpRequest object is called, wrapped in related functions in the configuration item, and once the required options are passed in, the corresponding send() method is called directly to request the data

2, Axios

The Promise based request library allows clients and Node servers to send requests based on the presence or presence of XMLHTTPRequest objects. It encapsulates a good HTTP library that supports promises, intercepts requests and responses, etc

Applets network request

wx.request({
  url: 'test.php'// This is an example, not a real interface address data: {x:' ',
    y: ' '
  },
  header: {
    'content-type': 'application/json'// Default value}, success (res) {console.log(res.data)}})Copy the code

The applets themselves are pretty well wrapped in requests and use them like $.Ajax, supporting many configuration items but lacking utility features such as common configuration, response, and request blocking

Step 1 — Create the request instance

class Axios {
  constructor() {this.instance = null // Class instance this.config = defaultConfig} create(instanceConfig) {const {config} = this // Add basic configuration this.config = {... config, ... instanceConfig }returnThis} // singleton staticgetInstance() {
    if(! this.instance) { this.instance = new Axios() }return this.instance
  }
}
Copy the code

Create an instance

const axios = Axios.getInstance()
Copy the code

Promise wraps the applets request

const dispatchRequest = function(config) {
  returnnew Promise((resolve, reject) => { wx.request({ ... config, url: config.base + config.url, success: res => { resolve(res) }, fail: res => { reject(res) } }) }) }Copy the code

Add the Request method to the request instance

Request (options) {const {config} = this // Add basic configuration when the instance requests const requsetOptions = {... config, ... options }return dispatchRequest(requsetOptions)
}
Copy the code

Step 2 – Create the request tool method

Create an instance and use create to set basic configuration items

const instance = (config = {}) => {
  returnaxios.create({ base: globalApi, ... config }) }Copy the code

Create request tool method that executes instance Request

export function request(options) {
  const { baseConfig, url, method, data, isLogin } = options
  instance(baseConfig)
    .request({
      url,
      method: method || 'GET',
      data
    })
    .then(res => {
      options.success && options.success(res)
    })
    .catch(err => {
      if (options.error) {
        options.error(err)
      } else {
        errAlert()
      }
    })
  }
}
Copy the code

This completes the utility method of a request, but the method now only supports the configuration of basic requests and basic configuration items, and still lacks the common request and response interception that we often use.

Step 3 – Add request and response interceptors

Create an interceptor instance

class InterceptorManager {
  constructor() {
    this.fulfilled = null
    this.rejected = null
  }

  use(fulfilled, rejected) {
    this.fulfilled = fulfilled
    this.rejected = rejected
  }
}
Copy the code

Add request and response interception instances to the request instance constructor

constructor() {this.instance = null // Class instance this.config = defaultConfig this.interceptors = {request: new InterceptorManager(), response: new InterceptorManager() } }Copy the code

Add the promise execution queue to the request of the instance

Request (options) {const {config, interceptors} = this const requsetOptions = {... config, ... Options} const promiseArr = [] // Promise storage queue // Request blocker promiseArr. Push ({depressing: Interceptors. Request. Fulfilled, rejected: interceptors. Request. The rejected}) / / request promiseArr. Push ({fulfilled: DispatchRequest, rejected: null}) / / callback interceptor promiseArr. Push ({fulfilled: interceptors. Response. Fulfilled, rejected: interceptors.response.rejected })let p = Promise.resolve(requsetOptions)
    promiseArr.forEach(ele => {
      p = p.then(ele['fulfilled'], ele['rejected'])})return p
  }
Copy the code

By setting interception methods for request and response in the request tool method

axios.interceptors.request.use(
  request => {
    return request
  },
  err => {
    console.error(err)
  }
)
Copy the code
axios.interceptors.response.use(
  response => {
    return response
  },
  err => {
    console.error(err)
  }
)
Copy the code

In the request interception method, you can add data conversion, add sign, token, etc. in the request header, and do common data processing in the response interception method

The last

It is easy to build a simple request library from scratch, but to consider all aspects of the design of the entire process is more troublesome, requiring constant improvement and reconstruction, the construction process of this article refers to part of the source code of Axios.