目录

🌓 静态方法拓展

# 需求分析

axios 还有 axios.allaxios.spread 等方法。

🌰 使用例子:

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

axios.all([getUserAccount(), getUserPermissions()])
  .then(axios.spread(function (acct, perms) {
    // Both requests are now complete
  }));
1
2
3
4
5
6
7
8
9
10
11
12

实际上, axios.all 就是 Promise.all 的封装,它返回的是一个 Promise 数组, then 函数的参数本应是一个参数为 Promise resolves (数组)的函数,在这里使用了 axios.spread 方法。所以 axios.spread 方法是接收一个函数,返回一个新的函数,新函数的结构满足 then 函数的参数结构。

其实使用 Promise 依旧可以完成这个需求。

function getUserAccount() {
  return axios.get('/user/12345');
}

function getUserPermissions() {
  return axios.get('/user/12345/permissions');
}

Promise.all([getUserAccount(), getUserPermissions()])
  .then(([acct,perms]) {
    // Both requests are now complete
  }));
1
2
3
4
5
6
7
8
9
10
11
12

Promise.allresolve 函数中,可以直接通过数组的解构拿到每个请求对应的响应对象。

为了与 axios 库能保持一致,所以要实现这两个方法。并且 axios 库中通过 axios.Axios 对外暴露了 Axios 类。还有提供 getUri 方法在不发送请求的前提下根据传入的配置返回一个 url

🌰 使用例子:

const fakeConfig = {
  baseURL: 'https://www.baidu.com/',
  url: '/user/12345',
  params: {
    idClient: 1,
    idTest: 2,
    testString: 'thisIsATest'
  }
}
console.log(axios.getUri(fakeConfig))
// https://www.baidu.com/user/12345?idClient=1&idTest=2&testString=thisIsATest
1
2
3
4
5
6
7
8
9
10
11

# 代码实现

修改类型定义( types/index.ts ):

export interface AxiosClassStatic {
  new (config: AxiosRequestConfig): Axios
}

export interface AxiosStatic extends AxiosInstance {
  // ...

  all<T>(promises: Array<T | Promise<T>>): Promise<T[]>

  spread<T, R>(callback: (...args: T[]) => R): (arr: T[]) => R

  Axios: AxiosClassStatic
}

export interface Axios {
  // ...

  getUri(config?: AxiosRequestConfig): string
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

然后实现这几个静态方法:

axios.all = function all(promises) {
  return Promise.all(promises)
}

axios.spread = function spread(callback) {
  return function wrap(arr) {
    return callback.apply(null, arr)
  }
}

axios.Axios = axios
1
2
3
4
5
6
7
8
9
10
11

最后给 Axios 添加实例方法 getUri

getUri(config?: AxiosRequestConfig): string {
  config = mergeConfig(this.defaults, config)
  return transformURL(config)
}
1
2
3
4

先使 config 与默认配置合并,然后再通过 transformURL 返回完整的 URL。

# 编写测试 DEMO

examples/more/app.ts

function getA() {
  return axios.get('/more/A')
}

function getB() {
  return axios.get('/more/B')
}

axios.all([getA(), getB()]).then(([resA, resB]) => {
  console.log(resA.data)
  console.log(resB.data)
})

const fakeConfig = {
  baseURL: 'https://www.baidu.com/',
  url: '/user/12345',
  params: {
    idClient: 1,
    idTest: 2,
    testString: 'thisIsATest'
  }
}
console.log(axios.getUri(fakeConfig))
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

通过 axios.all 同时发出两个请求,返回了 Promise 数组,可以在 axios.spread 参数函数中获得结果,也可直接在 then 函数中拿到结果。

📢 上次更新: 2022/09/02, 10:18:16