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

如何确保XMLHttpRequest完成响应后再返回完整结果数组?

解决XMLHttpRequest循环请求后无法返回完整响应数组的问题

原代码的核心问题是未将每个XMLHttpRequest请求包装为Promise,同时错误使用await和map,导致异步请求还未完成就提前返回空数组。具体问题点:

  • map是同步方法,await无法等待其内部的异步请求执行完毕
  • onreadystatechange会触发多次,未正确判断请求是否完成
  • 未将单个请求转化为Promise,无法通过Promise.all统一等待所有请求结束

修复方案

1. 封装单个XHR请求为Promise

先把单个XMLHttpRequest请求包装成Promise,明确处理成功和失败的情况:

// 封装XHR请求为Promise,确保请求完成后才返回结果
function fetchWithXHR(url) {
  return new Promise((resolve, reject) => {
    const xhr = new XMLHttpRequest();
    xhr.open('GET', url);
    xhr.responseType = 'json';
    
    // 请求成功完成时触发
    xhr.onload = () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        resolve(xhr.response);
      } else {
        reject(new Error(`请求失败,状态码:${xhr.status}`));
      }
    };
    
    // 网络错误时触发
    xhr.onerror = () => {
      reject(new Error('网络请求出错'));
    };
    
    xhr.send();
  });
}

2. 重构请求函数

利用Promise.all等待所有请求完成,返回完整的响应数组:

const getFetched = async () => {
  const requestURLArray = await getURLArray();
  // 把每个URL转为Promise,用Promise.all等待全部完成
  return Promise.all(requestURLArray.map(url => fetchWithXHR(url)));
};

3. 正确调用函数

使用async/await或.then()获取最终结果:

// 方式1:用.then()调用
getFetched().then(fetchedData => {
  console.log(fetchedData.length); // 现在会正确显示响应数量
  console.log(fetchedData); // 完整的响应数组
}).catch(error => {
  console.error('请求出错:', error);
});

// 方式2:用async/await调用
async function main() {
  try {
    const fetchedData = await getFetched();
    console.log(fetchedData.length);
    console.log(fetchedData);
  } catch (error) {
    console.error('请求出错:', error);
  }
}

main();

修复逻辑说明

  • 每个XHR请求被包装为Promise后,只有当请求成功完成(onload且状态码正常)才会resolve,出错则reject
  • requestURLArray.map生成Promise数组,Promise.all会等待所有Promise都resolve后,返回按顺序排列的完整响应数组
  • 去掉冗余的嵌套调用,用async/await让代码逻辑更清晰

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 14:35:23