扩展 axios.create 静态接口

需求分析

目前为止,我们的 axios 都是一个单例,一旦我们修改了 axios 的默认配置,会影响所有的请求。我们希望提供了一个 axios.create 的静态接口允许我们创建一个新的 axios 实例,同时允许我们传入新的配置和默认配置合并,并做为新的默认配置。

举个例子:

  1. const instance = axios.create({
  2. transformRequest: [(function(data) {
  3. return qs.stringify(data)
  4. }), ...(axios.defaults.transformRequest as AxiosTransformer[])],
  5. transformResponse: [...(axios.defaults.transformResponse as AxiosTransformer[]), function(data) {
  6. if (typeof data === 'object') {
  7. data.b = 2
  8. }
  9. return data
  10. }]
  11. })
  12. instance({
  13. url: '/config/post',
  14. method: 'post',
  15. data: {
  16. a: 1
  17. }
  18. })

静态方法扩展

由于 axios 扩展了一个静态接口,因此我们先来修改接口类型定义。

types/index.ts

  1. export interface AxiosStatic extends AxiosInstance{
  2. create(config?: AxiosRequestConfig): AxiosInstance
  3. }

create 函数可以接受一个 AxiosRequestConfig 类型的配置,作为默认配置的扩展,也可以接受不传参数。

接着我们来实现 axios.create 静态方法。

axios.ts

  1. function createInstance(config: AxiosRequestConfig): AxiosStatic {
  2. const context = new Axios(config)
  3. const instance = Axios.prototype.request.bind(context)
  4. extend(instance, context)
  5. return instance as AxiosStatic
  6. }
  7. axios.create = function create(config) {
  8. return createInstance(mergeConfig(defaults, config))
  9. }

内部调用了 createInstance 函数,并且把参数 configdefaults 合并,作为新的默认配置。注意这里我们需要 createInstance 函数的返回值类型为 AxiosStatic

demo 编写

  1. const instance = axios.create({
  2. transformRequest: [(function(data) {
  3. return qs.stringify(data)
  4. }), ...(axios.defaults.transformRequest as AxiosTransformer[])],
  5. transformResponse: [...(axios.defaults.transformResponse as AxiosTransformer[]), function(data) {
  6. if (typeof data === 'object') {
  7. data.b = 2
  8. }
  9. return data
  10. }]
  11. })
  12. instance({
  13. url: '/config/post',
  14. method: 'post',
  15. data: {
  16. a: 1
  17. }
  18. }).then((res) => {
  19. console.log(res.data)
  20. })

我们对上节课的示例做了小小的修改,通过 axios.create 方法创建一个新的实例 instance,并传入了 transformRequesttransformResponse 的配置修改了默认配置,然后通过 instance 发送请求,效果和之前是一样的。

至此我们实现了 axios.create 静态接口的扩展,整个 ts-axios 的配置化也告一段落。官方 axios 库还支持了对请求取消的能力,在发送请求前以及请求发送出去未响应前都可以取消该请求。下一章我们就来实现这个 feature。