标签搜索

调用API重新加载数据知识点

wehg489
2025-12-25 / 0 评论 / 1 阅读 / 正在检测是否收录...

try-catch错误捕获机制
try-catch-finally结构


try {
    // 尝试执行的代码,可能会抛出错误
    const result = await riskyOperation();
} catch (error) {
    // 捕获错误,进行错误处理
    console.error('操作失败:', error);
} finally {
    // 无论成功或失败都会执行的代码
    cleanup();
}

错误类型分类

try {
    await fetch('https://api.example.com/data');
} catch (error) {
    if (error instanceof TypeError) {
        // 网络错误或URL错误
        console.error('网络错误:', error.message);
    } else if (error instanceof SyntaxError) {
        // JSON解析错误
        console.error('数据格式错误');
    } else if (error.name === 'AbortError') {
        // 请求被取消
        console.error('请求超时');
    } else {
        // 其他未知错误
        console.error('未知错误:', error);
    }
}

异步操作:使用async/await处理异步API调用
async/await基本概念

// 传统Promise方式(回调地狱)
function oldWay() {
    fetch(url)
        .then(response => response.json())
        .then(data => {
            return processData(data);
        })
        .then(result => {
            console.log(result);
        })
        .catch(error => {
            console.error(error);
        });
}

// async/await方式(同步写法)
async function newWay() {
    try {
        const response = await fetch(url);
        const data = await response.json();
        const processed = await processData(data);
        console.log(processed);
    } catch (error) {
        console.error(error);
    }
}

await的工作机制

async function example() {
    console.log('1. 开始执行');
    
    // await会暂停函数执行,等待Promise完成
    const result = await someAsyncFunction();
    // ⬆️ 这里会"等待",但不会阻塞主线程
    
    console.log('3. 异步操作完成:', result);
}

console.log('0. 函数调用前');
example();
console.log('2. 函数已调用(不会等待)');
// 输出顺序: 0 → 1 → 2 → 3

并行与串行执行

// 1. 串行执行(一个接一个)
async function serialExecution() {
    console.time('串行');
    const result1 = await fetchData1(); // 等待2秒
    const result2 = await fetchData2(); // 等待3秒(等第一个完成后才开始)
    console.timeEnd('串行'); // 总耗时≈5秒
}

// 2. 并行执行(同时进行)
async function parallelExecution() {
    console.time('并行');
    const promise1 = fetchData1(); // 立即开始,不等待
    const promise2 = fetchData2(); // 立即开始,不等待
    
    // 使用Promise.all同时等待多个Promise
    const [result1, result2] = await Promise.all([promise1, promise2]);
    console.timeEnd('并行'); // 总耗时≈3秒(取最长的)
}

// 3. 竞赛模式(谁先完成用谁)
async function raceExecution() {
    const result = await Promise.race([
        fetchWithTimeout('api1', 2000),
        fetchWithTimeout('api2', 2000)
    ]);
    // 第一个完成的(无论成功或失败)会被返回
}

错误处理模式对比

// 模式1:每个await单独try-catch
async function individualCatch() {
    let data;
    try {
        data = await fetchData();
    } catch (error) {
        console.error('获取数据失败:', error);
        return;
    }
    
    try {
        await processData(data);
    } catch (error) {
        console.error('处理数据失败:', error);
    }
}

// 模式2:统一错误处理
async function unifiedCatch() {
    try {
        const data = await fetchData();
        await processData(data);
        await saveData(data);
    } catch (error) {
        // 任何一个步骤失败都会跳到这里
        handleError(error);
    }
}

// 模式3:使用高阶函数包装
function withErrorHandling(asyncFunc) {
    return async function(...args) {
        try {
            return await asyncFunc(...args);
        } catch (error) {
            console.error('函数执行失败:', error);
            return { error: true, message: error.message };
        }
    };
}

const safeFetch = withErrorHandling(fetchData);
const result = await safeFetch(url);

实际案例

<script>
    // 当DOM内容完全加载后执行(确保所有HTML元素已存在)
    document.addEventListener('DOMContentLoaded', function() {
        // 获取页面中的按钮元素
        const reloadBtn = document.getElementById('reload-btn');
        // 获取显示结果的div元素
        const resultDiv = document.getElementById('result');
        // 获取显示服务器URL的span元素(虽然代码中未使用,但已定义)
        const serverUrlSpan = document.getElementById('server-url');
        
        // 获取当前页面的主机名和端口号,用于构建API URL(备用)
        const currentHost = window.location.hostname;
        const currentPort = window.location.port;

        // 为"更新数据"按钮添加点击事件监听器
        reloadBtn.addEventListener('click', async function() {
            // 禁用按钮,防止用户重复点击
            reloadBtn.disabled = true;
            // 更改按钮文字提示用户正在更新
            reloadBtn.textContent = '更新中...';
            
            // 清空之前显示的结果
            resultDiv.className = 'hidden'; // 添加隐藏类
            resultDiv.innerHTML = '';       // 清空内容
            
            try {
                // 显示加载状态
                resultDiv.className = 'loading'; // 添加加载样式类
                resultDiv.textContent = '正在重新加载数据...';
                resultDiv.classList.remove('hidden'); // 移除隐藏类,显示div
                
                // 调用API发送POST请求到指定端点
                const response = await fetch(`https://api.demo.top/api/reload`, {
                    method: 'POST', // 使用POST方法
                    headers: {
                        'Content-Type': 'application/json' // 设置请求头为JSON格式
                    }
                });
                
                // 将响应解析为JSON格式
                const result = await response.json();
                
                // 根据API返回的成功状态设置结果显示样式
                resultDiv.className = result.success ? 'success' : 'error';
                
                // 构建要显示的结果HTML内容
                let html = '';
                
                if (result.success) {
                    // 成功情况的显示内容
                    html += '<div class="status-line"><strong>✅ 数据重载成功</strong></div>';
                    html += `<div class="status-line">${result.message}</div>`;
                    
                    // 如果有详细数据,显示详细信息
                    if (result.data) {
                        html += '<hr style="margin: 15px 0;">'; // 添加分隔线
                        html += '<div class="status-line"><strong>详细信息:</strong></div>';
                        html += `<div class="status-line">重载前: ${result.data.before} 条记录</div>`;
                        html += `<div class="status-line">重载后: ${result.data.after} 条记录</div>`;
                        html += `<div class="status-line">变化: ${result.data.difference > 0 ? '+' : ''}${result.data.difference} 条记录</div>`;
                        html += `<div class="status-line">时间: ${result.data.timestamp}</div>`;
                    }
                } else {
                    // 失败情况的显示内容
                    html += '<div class="status-line"><strong>❌ 数据重载失败</strong></div>';
                    html += `<div class="status-line">${result.message}</div>`;
                    
                    // 如果有错误详情,显示错误信息
                    if (result.error) {
                        html += `<div class="status-line">错误: ${result.error}</div>`;
                    }
                }
                
                // 将构建的HTML插入结果div
                resultDiv.innerHTML = html;
                
            } catch (error) {
                // 捕获网络错误或其他异常
                resultDiv.className = 'error';
                resultDiv.innerHTML = `
                    <div class="status-line"><strong>❌ 请求失败</strong></div>
                    <div class="status-line">无法连接到服务器</div>
                    <div class="status-line">错误: ${error.message}</div>
                    <div class="status-line">请确保服务器正在运行</div>
                `;
            } finally {
                // 无论成功或失败,最后都会执行这里
                // 恢复按钮的可用状态
                reloadBtn.disabled = false;
                // 恢复按钮文字
                reloadBtn.textContent = '更新数据';
            }
        });
    });
</script>
0

评论 (0)

取消
歌曲封面
0:00