MST

星途 面试题库

面试题:Vue前端架构下复杂网络请求场景的异步与错误管理优化

在一个大型Vue前端项目中,存在多种类型的网络请求,包括普通GET/POST请求、文件上传、长轮询等。如何从架构层面设计一套统一的异步处理和错误捕获机制,以提高代码的可维护性、复用性和性能?阐述详细的设计思路、涉及到的技术点以及关键代码结构。
35.3万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 封装请求模块:将不同类型的网络请求封装成独立的函数,便于复用。
  2. 统一异步处理:使用Promise或async/await来处理异步操作,使得代码更简洁、易读。
  3. 错误捕获:在统一的地方捕获请求过程中的错误,避免重复编写try - catch块。
  4. 队列管理:对于长轮询等特殊请求,考虑使用队列来管理,防止过多请求同时发起影响性能。

技术点

  1. Axios:一个流行的基于Promise的HTTP客户端,可用于发送GET/POST等请求,同时支持文件上传。
  2. Promise:用于处理异步操作,提供了then、catch等方法来处理成功和失败的情况。
  3. async/await:基于Promise的语法糖,让异步代码看起来像同步代码,提高可读性。

关键代码结构

  1. 请求封装
import axios from 'axios';

// 普通GET请求
export const getRequest = (url, params = {}) => {
    return axios.get(url, { params });
};

// 普通POST请求
export const postRequest = (url, data = {}) => {
    return axios.post(url, data);
};

// 文件上传
export const uploadRequest = (url, formData) => {
    return axios.post(url, formData, {
        headers: {
            'Content-Type':'multipart/form-data'
        }
    });
};

// 长轮询
let pollingTimer;
export const longPolling = (url, interval = 3000) => {
    return new Promise((resolve, reject) => {
        const poll = () => {
            axios.get(url)
              .then(response => {
                    resolve(response);
                    pollingTimer = setTimeout(poll, interval);
                })
              .catch(error => {
                    reject(error);
                    pollingTimer = setTimeout(poll, interval);
                });
        };
        poll();
    });
};
  1. 统一错误捕获
// 创建一个axios实例
const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API, // api的base_url
    timeout: 5000 // 请求超时时间
});

// 添加请求拦截器
service.interceptors.request.use(config => {
    // 这里可以做一些请求前的处理,如添加token等
    return config;
}, error => {
    return Promise.reject(error);
});

// 添加响应拦截器
service.interceptors.response.use(response => {
    // 这里可以对响应数据做一些统一处理,如处理code码等
    return response.data;
}, error => {
    // 统一错误处理
    console.error('请求错误:', error);
    return Promise.reject(error);
});
  1. 在Vue组件中使用
<template>
    <div>
        <!-- 组件内容 -->
    </div>
</template>

<script>
import { getRequest, postRequest, uploadRequest, longPolling } from '@/api';

export default {
    name: 'ExampleComponent',
    methods: {
        async fetchData() {
            try {
                const response = await getRequest('/api/data');
                console.log('GET请求成功:', response);
            } catch (error) {
                console.error('GET请求失败:', error);
            }
        },
        async submitForm() {
            try {
                const response = await postRequest('/api/submit', { key: 'value' });
                console.log('POST请求成功:', response);
            } catch (error) {
                console.error('POST请求失败:', error);
            }
        },
        async uploadFile() {
            const formData = new FormData();
            formData.append('file', this.file);
            try {
                const response = await uploadRequest('/api/upload', formData);
                console.log('文件上传成功:', response);
            } catch (error) {
                console.error('文件上传失败:', error);
            }
        },
        async startPolling() {
            try {
                const response = await longPolling('/api/polling');
                console.log('长轮询成功:', response);
            } catch (error) {
                console.error('长轮询失败:', error);
            }
        }
    }
};
</script>