axios为什么可以使用对象和函数两种方式调用?是如何实现的?

Axios 可以使用对象和函数两种方式调用,是因为它的核心 API 设计利用了函数重载和 JavaScript 的灵活性。 本质上,Axios 暴露的顶层 axios 对象既是一个函数,又是一个拥有属性的对象。

以下是它的实现方式:

  1. Axios 对象是一个函数: 当你像这样调用 axios(config) 时,你实际上是在直接调用 Axios 对象本身。这个函数内部会处理配置 config,并发起请求。

  2. Axios 对象拥有方法 (HTTP verbs): axios.get(url[, config])axios.post(url[, data[, config]]) 等方法是 Axios 对象的属性。这些方法是对 axios() 函数的封装,它们预设了 HTTP 方法,并简化了常见请求的调用方式。 例如,axios.get(url, config) 内部会调用 axios({...config, method: 'get', url})

  3. 函数重载 (通过参数类型判断): axios() 函数内部会根据传入参数的类型进行不同的处理。如果传入的是一个配置对象 config,它会直接使用这个配置发起请求。如果传入的是 URL 字符串,它会将 URL 视为 config.url,并创建一个默认的 GET 请求配置。

// Simplified example of how axios might be implemented internally

function axios(configOrUrl, data, config) {
  let finalConfig = {};

  if (typeof configOrUrl === 'string') { // URL as first argument
    finalConfig.url = configOrUrl;
    finalConfig.method = 'get'; // Default to GET
    if (data) { // Second argument is data if provided
       finalConfig.data = data;
    }
    if (config) { // Third argument is config
      finalConfig = { ...finalConfig, ...config };
    }

  } else if (typeof configOrUrl === 'object') { // Config object as first argument
    finalConfig = { ...configOrUrl };
    if (data) {
      finalConfig.data = data; // Overwrite data if provided as second argument (less common)
    }
  } else {
    throw new Error('Invalid arguments provided to axios');
  }

  // ... rest of the axios logic to make the request using finalConfig
  return makeRequest(finalConfig);
}


// Adding HTTP verb methods to the axios object
axios.get = function(url, config) {
  return axios({ ...config, method: 'get', url });
};

axios.post = function(url, data, config) {
  return axios({ ...config, method: 'post', url, data });
};

// ... other HTTP verb methods (put, delete, patch, etc.)

// Example usage:

// Object style
axios({
  method: 'post',
  url: '/user/12345',
  data: {
    firstName: 'Fred',
    lastName: 'Flintstone'
  }
});

// Function style (GET)
axios('/user/12345').then(response => { /* ... */ });

// Function style (POST) - less common, can be confusing
axios('/user/12345', { firstName: 'Fred' }).then(response => { /* ... */ });


// Using convenience methods
axios.get('/user/12345').then(response => { /* ... */ });
axios.post('/user/12345', { firstName: 'Fred' }).then(response => { /* ... */ });

通过这种巧妙的设计,Axios 提供了灵活的 API,开发者可以根据自己的喜好和需求选择不同的调用方式。 使用对象方式可以进行更精细的配置,而使用函数方式则更加简洁方便。

posted @ 2024-12-06 09:42  王铁柱6  阅读(35)  评论(0)    收藏  举报