JavaScript promise实例——通过XHR获取省份列表
文章目录
- 需求和步骤
- 代码示例
- 效果
 
需求和步骤

代码示例
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <!-- 确保IE浏览器使用最新的渲染引擎 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <!-- 设置viewport以确保页面在移动设备上正确显示 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Promise管理XHR请求</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            padding: 20px;
            max-width: 800px;
            margin: 0 auto;
        }
        
        button {
            padding: 10px 20px;
            background-color: #4CAF50;
            color: white;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 16px;
        }
        
        button:hover {
            background-color: #45a049;
        }
        
        .my-p {
            margin-top: 20px;
            padding: 15px;
            background-color: #f5f5f5;
            border-radius: 4px;
            line-height: 1.8;
        }
        
        .log {
            margin-top: 20px;
            padding: 15px;
            background-color: #f8f9fa;
            border: 1px solid #ddd;
            border-radius: 4px;
            font-family: monospace;
            white-space: pre-wrap;
            max-height: 300px;
            overflow: auto;
        }
    </style>
</head>
<body>
    <h2>Promise管理XHR省份列表请求示例</h2>
    <button id="getProvinces">获取省份列表</button>
    <p class="my-p">点击按钮加载省份列表...</p>
    <div class="log" id="log">日志输出:</div>
    <script>
        // 添加日志输出函数
        function log(message) {
            console.log(message);
            const logElement = document.getElementById('log');
            logElement.textContent += '\n' + message;
        }
        
        // 监听按钮点击事件
        document.getElementById('getProvinces').addEventListener('click', () => {
            log('按钮被点击,开始请求省份列表...');
            // 调用获取省份列表的函数
            getProvinceList();
        });
        
        // 获取省份列表函数
        function getProvinceList() {
            // 目标:使用Promise管理XHR请求省份列表
            log('开始创建Promise...');
            
            // 1.创建Promise对象
            const p = new Promise((resolve, reject) => {
                log('Promise回调函数开始执行');
                
                // 2.执行XHR异步代码,获取省份列表
                const xhr = new XMLHttpRequest();
                log('创建XHR对象成功');
                
                xhr.open('GET', 'http://hmajax.itheima.net/api/province');
                log('配置请求方法和URL完成');
                
                xhr.addEventListener('loadend', () => {
                    log(`XHR请求完成,状态码: ${xhr.status}`);
                    log(`响应数据: ${xhr.response}`);
                    
                    // xhr如何判断响应成功还是失败的?
                    // 2xx开头的都是成功响应状态码
                    if (xhr.status >= 200 && xhr.status < 300) {
                        log('XHR请求成功,触发resolve...');
                        resolve(JSON.parse(xhr.response));
                    } else {
                        log('XHR请求失败,触发reject...');
                        reject(new Error(xhr.response));
                    }
                });
                
                // 监听错误事件
                // loadend事件只能捕获到服务器返回的错误(如404、500等HTTP错误)
                // 但无法捕获到请求根本没有到达服务器的情况
                // error事件填补了这个空缺,处理网络层面的错误
                xhr.addEventListener('error', () => {
                    log('XHR请求发生网络错误');
                    reject(new Error('网络错误,请检查您的网络连接'));
                });
                
                log('准备发送XHR请求...');
                xhr.send();
                log('XHR请求已发送,等待响应...');
            });
            
            // 3.关联成功或失败函数,做后续处理
            log('关联Promise的成功和失败处理函数...');
            p.then(result => {
                log('Promise已成功解决(resolved)');
                log(`解析后的结果: ${JSON.stringify(result)}`);
                
                // 将省份列表显示在页面上
                document.querySelector('.my-p').innerHTML = result.list.join('<br>');
            }).catch(error => {
                log('Promise已拒绝(rejected)');
                
                // 错误对象要用console.dir详细打印
                console.dir(error);
                log(`错误信息: ${error.message}`);
                
                // 服务器返回错误提示消息,插入到p标签显示
                document.querySelector('.my-p').innerHTML = error.message;
            });
        }
    </script>
</body>
</html>
效果

 
 
