面试题答案
一键面试错误处理机制设计
- 网络错误处理:
- 使用
fetch
或axios
进行文件上传时,在catch
块中捕获网络错误。例如,使用axios
:
import axios from 'axios'; const handleFileUpload = async (file) => { try { const formData = new FormData(); formData.append('file', file); await axios.post('/upload', formData, { headers: { 'Content-Type':'multipart/form-data' } }); } catch (error) { if (error.response) { // 服务器返回了错误状态码 console.error('服务器错误:', error.response.status); } else if (error.request) { // 请求已发出,但没有收到响应 console.error('网络错误,没有收到响应'); } else { // 其他错误 console.error('请求设置时出错:', error.message); } } };
- 使用
- 文件类型不匹配处理:
- 在上传前对文件类型进行验证。可以通过
input[type="file"]
的accept
属性来限制用户选择的文件类型,也可以在代码中手动验证。例如:
const handleFileUpload = (file) => { const allowedTypes = ['image/jpeg', 'image/png', 'application/pdf']; if (!allowedTypes.includes(file.type)) { console.error('文件类型不匹配,仅允许', allowedTypes.join(', '), '类型的文件'); return; } // 继续上传逻辑 };
- 在上传前对文件类型进行验证。可以通过
- 文件大小限制处理:
- 在上传前获取文件大小并进行限制。例如:
const handleFileUpload = (file) => { const maxSize = 5 * 1024 * 1024; // 5MB if (file.size > maxSize) { console.error('文件大小超过限制,最大允许 5MB'); return; } // 继续上传逻辑 };
优化文件上传过程以提高用户体验
- 进度条显示:
- 使用
XMLHttpRequest
或fetch
的ProgressEvent
来实现进度条。以fetch
为例:
const handleFileUpload = async (file) => { const formData = new FormData(); formData.append('file', file); const controller = new AbortController(); const { signal } = controller; const response = await fetch('/upload', { method: 'POST', body: formData, signal }); const xhr = new XMLHttpRequest(); xhr.open('POST', '/upload', true); xhr.upload.onprogress = function (e) { if (e.lengthComputable) { const percentComplete = (e.loaded / e.total * 100).toFixed(2); console.log('上传进度:', percentComplete + '%'); // 在这里更新进度条 UI } }; xhr.send(formData); };
- 使用
- 并发控制:
- 如果有多个文件上传需求,可以限制并发数量,避免过多请求占用网络资源。例如,可以使用
Promise.allSettled
结合队列控制并发数:
const uploadFiles = (files, maxConcurrent = 3) => { const queue = []; const results = []; for (let i = 0; i < files.length; i++) { const file = files[i]; const uploadTask = () => { return new Promise((resolve, reject) => { // 上传逻辑,例如使用 axios const formData = new FormData(); formData.append('file', file); axios.post('/upload', formData, { headers: { 'Content-Type':'multipart/form-data' } }) .then(() => resolve()) .catch((error) => reject(error)); }); }; queue.push(uploadTask); } const processQueue = async () => { while (queue.length > 0) { const currentTasks = queue.splice(0, maxConcurrent); const taskResults = await Promise.allSettled(currentTasks.map(task => task())); results.push(...taskResults); } return results; }; return processQueue(); };
- 如果有多个文件上传需求,可以限制并发数量,避免过多请求占用网络资源。例如,可以使用
- 用户反馈:
- 在上传开始时,显示加载指示器,告知用户上传正在进行。上传成功或失败后,给出明确的提示信息,如“文件上传成功”或“文件上传失败,请重试”。可以使用 React 的
useState
和useEffect
来管理和更新这些状态。
import React, { useState, useEffect } from'react'; const FileUploadComponent = () => { const [isUploading, setIsUploading] = useState(false); const [uploadStatus, setUploadStatus] = useState(''); const handleFileUpload = (file) => { setIsUploading(true); // 上传逻辑 setTimeout(() => { setIsUploading(false); setUploadStatus('文件上传成功'); }, 3000); }; return ( <div> <input type="file" onChange={(e) => handleFileUpload(e.target.files[0])} /> {isUploading && <p>上传中...</p>} {uploadStatus && <p>{uploadStatus}</p>} </div> ); }; export default FileUploadComponent;
- 在上传开始时,显示加载指示器,告知用户上传正在进行。上传成功或失败后,给出明确的提示信息,如“文件上传成功”或“文件上传失败,请重试”。可以使用 React 的