You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现可复用的异步XMLHttpRequest函数,按顺序执行请求并等待响应

问题根源

XMLHttpRequest为异步执行模型,onreadystatechange回调函数的返回值无法传递给外层getRequest函数,getRequest在执行xr.send()后会直接返回,不会等待请求完成,因此拿到的temp为undefined。

改造方案:用Promise封装通用请求函数

该方案完全不会破坏函数复用性,通用的请求逻辑全部封装在底层,不同请求的业务处理逻辑可以完全独立编写,同时天然支持等待请求完成、按顺序发起多个请求的需求,不需要自行实现变量监听逻辑。

function getRequest(URL) {
    const akey = '000';
    // 返回Promise实例,外部可通过await/then等待结果
    return new Promise((resolve, reject) => {
        const xr = new XMLHttpRequest();
        xr.open("GET", URL);
        xr.setRequestHeader("X-API-Key", akey);

        xr.onreadystatechange = () => {
            if (xr.readyState === 4) {
                // 请求成功状态判断
                if (xr.status >= 200 && xr.status < 300) {
                    try {
                        const xh = JSON.parse(xr.responseText);
                        resolve(xh); // 将请求结果抛给外层调用方
                    } catch (e) {
                        reject(new Error('响应数据解析失败'));
                    }
                } else {
                    reject(new Error(`请求失败,状态码:${xr.status}`));
                }
            }
        };
        // 网络异常捕获
        xr.onerror = () => reject(new Error('网络请求异常'));
        xr.send();
    });
}
调用方式

方式1:async/await语法(更适合顺序请求场景)

通用请求逻辑全部封装在getRequest内,业务处理逻辑独立编写,不存在复用性被破坏的问题:

async function BClick(){
    try {
        const rqURL = 'https://endpoint';
        // 等待请求完成后再执行后续代码
        const temp = await getRequest(rqURL);
        console.log(temp);
        // 此处编写当前请求的专属处理逻辑
    } catch (e) {
        // 统一处理请求错误
        console.error(e.message);
    }
}

如果需要按顺序发起多个请求,依次执行await即可:

async function sequentialRequest() {
    // 第一个请求完成后才会发起第二个请求
    const statisticsData = await getRequest('统计数据API地址');
    // 处理统计数据逻辑
    const bagData = await getRequest('背包库存API地址');
    // 处理背包数据逻辑
}

方式2:then链调用(适合回调风格场景)

function BClick(){
    const rqURL = 'https://endpoint';
    getRequest(rqURL)
        .then(temp => {
            console.log(temp);
            // 此处编写当前请求的专属处理逻辑
        })
        .catch(e => {
            console.error(e.message);
        });
}

顺序发起多个请求的写法:

function sequentialRequest() {
    getRequest('统计数据API地址')
        .then(statisticsData => {
            // 处理统计数据逻辑
            return getRequest('背包库存API地址');
        })
        .then(bagData => {
            // 处理背包数据逻辑
        })
        .catch(e => console.error(e));
}
方案优势
  • 完全保留通用请求函数的复用性,header设置、JSON解析、错误捕获等通用逻辑全部封装在getRequest内,无需重复编写
  • 原生支持等待请求完成的需求,无需自行实现变量监听逻辑
  • 顺序请求的逻辑清晰易维护,匹配你需要按顺序发起多个API请求的场景
  • 错误处理统一,不需要每个请求单独写状态判断逻辑

内容的提问来源于stack exchange,提问作者knighToFdemonS

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 19:15:04