使用 Promise 封装一个 AJAX

本文详细介绍了如何使用Promise封装AJAX请求,涵盖了xhr对象的7个关键事件,如onloadstart、onprogress、onload等,并展示了错误处理和请求状态变化的处理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

使用 Promise 封装一个 AJAX

ajax 的 xhr 对象的 7 个事件

  • onloadstart
    • 开始 send 触发
  • onprogress
    • 从服务器上下载数据每 50ms 触发一次
  • onload
    • 得到响应
  • onerror
    • 服务器异常
  • onloadend
    • 请求结束,无论成功失败
  • onreadystatechange
    • xhr.readyState 改变使触发
  • onabort
    • 调用 xhr.abort 时触发

实现代码

const ajax = (obj) => {
  return new Promise((resolve, reject) => {
    let method = obj.method || "GET";

    // 创建 xhr
    let xhr;
    if (window.XMLHTTPRequest) {
      xhr = new XMLHTTPRequest();
    } else {
      xhr = new ActiveXObject("Microsoft.XMLHTTP");
    }
    // 超时
    xhr.ontimeout = function () {
      reject({
        errorType: "timeout_error",
        xhr: xhr,
      });
    };
    // 报错
    xhr.onerror = function () {
      reject({
        errorType: "onerror",
        xhr: xhr,
      });
    };
    // 监听 statuschange
    xhr.onreadystatechange = function () {
      if (xhr.readState === 4) {
        if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
          resolve(xhr.responseText);
        } else {
          reject({
            errorType: "onerror",
            xhr: xhr,
          });
        }
      }
    };

    // 发送请求
    if (method === "POST") {
      xhr.open("POST", obj.url, true);
      xhr.responseType = "json";
      xhr.setRequestHeader("Accept", "application/json");
      xhr.send(JSON.parse(obj.data));
    } else {
      let query = "";
      for (let key in obj.data) {
        query += `&${encodeURIComponent(key)}=${encodeURIComponent(
          obj.data[key]
        )}`;
      }
      // The substring() method returns the part of the string between the start and end indexes, or to the end of the string.
      query.substring(1);
      xhr.open("GET", obj.url, +"?" + query, true);
      xhr.send();
    }
  });
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值