import { useState, useEffect } from 'react' import { Link } from 'wouter' interface UploadProgress { id: string name: string progress: number status: 'uploading' | 'completed' | 'error' speed: string timeRemaining: string } interface DataItem { id: number title: string content: string timestamp: string status: 'loading' | 'loaded' | 'error' } export default function AsyncTestPage() { const [uploads, setUploads] = useState([]) const [dataItems, setDataItems] = useState([]) const [isLoadingData, setIsLoadingData] = useState(false) const [realTimeData, setRealTimeData] = useState([]) const [isRealTimeActive, setIsRealTimeActive] = useState(false) const [longRunningTask, setLongRunningTask] = useState<{ isRunning: boolean progress: number currentStep: string logs: string[] }>({ isRunning: false, progress: 0, currentStep: '', logs: [] }) // 模拟实时数据更新 useEffect(() => { let interval: NodeJS.Timeout if (isRealTimeActive) { interval = setInterval(() => { const newData = `数据更新 ${new Date().toLocaleTimeString()}: ${Math.floor(Math.random() * 1000)}` setRealTimeData(prev => [newData, ...prev.slice(0, 9)]) // 保持最新10条 }, 2000) } return () => { if (interval) clearInterval(interval) } }, [isRealTimeActive]) // 模拟文件上传 const simulateFileUpload = (fileName: string) => { const uploadId = Date.now().toString() const newUpload: UploadProgress = { id: uploadId, name: fileName, progress: 0, status: 'uploading', speed: '0 KB/s', timeRemaining: '计算中...' } setUploads(prev => [...prev, newUpload]) // 模拟上传进度 const interval = setInterval(() => { setUploads(prev => prev.map(upload => { if (upload.id === uploadId) { const newProgress = Math.min(upload.progress + Math.random() * 15, 100) const speed = `${(Math.random() * 500 + 100).toFixed(0)} KB/s` const timeRemaining = newProgress >= 100 ? '完成' : `${Math.ceil((100 - newProgress) / 10)}秒` // 模拟随机失败 if (newProgress > 50 && Math.random() < 0.1) { clearInterval(interval) return { ...upload, status: 'error' as const, speed: '0 KB/s', timeRemaining: '失败' } } if (newProgress >= 100) { clearInterval(interval) return { ...upload, progress: 100, status: 'completed' as const, speed, timeRemaining } } return { ...upload, progress: newProgress, speed, timeRemaining } } return upload })) }, 500) } // 模拟数据加载 const loadData = async () => { setIsLoadingData(true) setDataItems([]) // 创建骨架屏数据 const skeletonItems: DataItem[] = Array.from({ length: 6 }, (_, i) => ({ id: i, title: '', content: '', timestamp: '', status: 'loading' })) setDataItems(skeletonItems) // 逐个加载数据项 for (let i = 0; i < 6; i++) { await new Promise(resolve => setTimeout(resolve, 800 + Math.random() * 1000)) setDataItems(prev => prev.map(item => { if (item.id === i) { // 模拟随机加载失败 if (Math.random() < 0.15) { return { ...item, status: 'error', title: '加载失败', content: '数据加载失败,请重试' } } return { ...item, status: 'loaded', title: `数据项 ${i + 1}`, content: `这是第 ${i + 1} 个数据项的内容,包含了一些示例文本用于展示加载效果。`, timestamp: new Date().toLocaleString() } } return item })) } setIsLoadingData(false) } // 模拟长时间运行的任务 const startLongRunningTask = async () => { setLongRunningTask({ isRunning: true, progress: 0, currentStep: '初始化任务...', logs: ['任务开始'] }) const steps = [ { name: '初始化任务...', duration: 2000 }, { name: '连接服务器...', duration: 1500 }, { name: '验证权限...', duration: 1000 }, { name: '下载数据...', duration: 3000 }, { name: '处理数据...', duration: 2500 }, { name: '生成报告...', duration: 2000 }, { name: '保存结果...', duration: 1000 }, { name: '清理资源...', duration: 500 } ] for (let i = 0; i < steps.length; i++) { const step = steps[i] setLongRunningTask(prev => ({ ...prev, currentStep: step.name, logs: [...prev.logs, `开始: ${step.name}`] })) // 模拟步骤执行时间 const startTime = Date.now() while (Date.now() - startTime < step.duration) { await new Promise(resolve => setTimeout(resolve, 100)) const elapsed = Date.now() - startTime const stepProgress = Math.min((elapsed / step.duration) * 100, 100) const totalProgress = ((i + stepProgress / 100) / steps.length) * 100 setLongRunningTask(prev => ({ ...prev, progress: totalProgress })) } setLongRunningTask(prev => ({ ...prev, logs: [...prev.logs, `完成: ${step.name}`] })) // 模拟随机失败 if (i === 3 && Math.random() < 0.2) { setLongRunningTask(prev => ({ ...prev, isRunning: false, currentStep: '任务失败', logs: [...prev.logs, '错误: 数据下载失败,请重试'] })) return } } setLongRunningTask(prev => ({ ...prev, isRunning: false, progress: 100, currentStep: '任务完成', logs: [...prev.logs, '任务成功完成!'] })) } const clearUploads = () => { setUploads([]) } const retryFailedUpload = (uploadId: string) => { const failedUpload = uploads.find(u => u.id === uploadId) if (failedUpload) { setUploads(prev => prev.filter(u => u.id !== uploadId)) simulateFileUpload(failedUpload.name) } } const retryDataLoad = (itemId: number) => { setDataItems(prev => prev.map(item => { if (item.id === itemId) { return { ...item, status: 'loading', title: '', content: '', timestamp: '' } } return item })) setTimeout(() => { setDataItems(prev => prev.map(item => { if (item.id === itemId) { return { ...item, status: 'loaded', title: `数据项 ${itemId + 1}`, content: `这是重新加载的第 ${itemId + 1} 个数据项的内容。`, timestamp: new Date().toLocaleString() } } return item })) }, 1000) } return (

异步操作测试

测试等待、加载状态识别和异步操作处理能力

{/* 文件上传进度 */}

文件上传进度

{uploads.length === 0 ? (
点击"开始上传"来模拟文件上传
) : ( uploads.map(upload => (
{upload.name} {upload.status === 'completed' ? '✓ 完成' : upload.status === 'error' ? '✗ 失败' : '上传中...'}
{upload.progress.toFixed(1)}% {upload.speed} {upload.timeRemaining}
{upload.status === 'error' && ( )}
)) )}
{/* 实时数据更新 */}

实时数据更新

{realTimeData.length === 0 ? (
点击"开始更新"来查看实时数据
) : ( realTimeData.map((data, index) => (
{data}
)) )}
{/* 数据加载和长时间任务 */}
{/* 数据加载骨架屏 */}

数据加载测试

{dataItems.map(item => (
{item.status === 'loading' ? (
) : item.status === 'error' ? (

{item.title}

{item.content}

) : (

{item.title}

{item.content}

{item.timestamp}
)}
))}
{/* 长时间运行任务 */}

长时间任务

{longRunningTask.progress > 0 && (
{longRunningTask.currentStep} {longRunningTask.progress.toFixed(1)}%
)} {longRunningTask.logs.length > 0 && (

执行日志:

{longRunningTask.logs.map((log, index) => (
{log}
))}
)}
{/* 返回链接 */}
← 返回测试页面列表
) }