浅入理解Ajax,实现一个Ajax的封装,直接可以用

1,612 阅读3分钟

什么是Ajax

Ajax是一项前端js技术,实现的功能是向服务器发送异步请求,优点是不必刷新页面就可以改变页面内容,提高了页面的响应速度和用户的体验。

image.png

实现思路

  1. 创建XMLHttpRequest对象

    使用JavaScript中的XMLHttpRequest对象,可以发起对服务器的异步请求。这个对象可以在浏览器中通过以下方式创建:

var xhr = new XMLHttpRequest();
  1. 发送请求并处理响应

    使用XMLHttpRequest对象的open方法设置请求方法和请求地址,然后通过send方法发送请求。当服务器返回响应时,XMLHttpRequest对象会触发readystatechange事件,我们可以在事件的回调函数中处理服务器返回的数据。核心代码如下:

var xhr = new XMLHttpRequest();
xhr.open("GET", "http://example.com/data.json");
xhr.send();
xhr.onreadystatechange = function() {
  if(xhr.readyState == 4 && xhr.status == 200) {
    var data = JSON.parse(xhr.responseText);
    // 处理返回的数据
  }
}
  1. 更新页面内容

image.png

其他细节

参数拼接

我们拿到的参数一般是一个对象params,长成这个样子:↓

params={
    username:"liuqi",
    userpsd:123456
}

我们需要将其拼接成网址上的形式,也就是介个↓

username=liuqi&userpsd=123456

思路很简单,用数组方法reduce就可以了

image.png

返回promise

为了避免函数嵌套,增加代码可读性和便于管理,所以我们封装的时候都会返回promise对象。

Ajax是一种异步请求的方式,它可以让页面在不重新加载的情况下更新数据,交互更加流畅。但是,在实际开发中,我们可能需要同时发送多个Ajax请求,并需要等待这些请求全部完成后再进行下一步操作,这就需要用到Promise。

使用Promise可以更好地处理异步操作的状态,我们可以将每个Ajax请求都封装成Promise对象,并将Promise对象存储到数组中,然后通过Promise.all方法来等待所有的Promise对象都完成后再进行下一步操作。这样的代码结构更加清晰,可读性更好,而不是使用回调函数进行嵌套处理。

使用Promise还可以让我们更好地处理Ajax请求的错误状态,当异步请求出错时,Promise可以将错误信息传递到catch方法中,从而避免代码中的try/catch嵌套,降低代码复杂度。

综合来说,使用Promise可以更好地处理异步操作的状态和错误,使得代码更加简洁易懂,降低了代码的维护成本。

完整代码

const myAjax = (obj) => {
  // 首先处理接收的obj,我们需要新增一个paramsObj
  // 里面可以填一些默认值,作用是在obj中缺少对应值的时候也能运行
  // 或者让obj可以少传递一些重复值
  let paramsObj = {
    method: "get",
    params: {},
    baseUrl: "http://cxk520.top:3000",
    ...obj,
  };
  let { method, baseUrl, params, url } = paramsObj;

  method = method.toLowerCase();

  const parsePar = (params) =>
    Object.keys(params)
      .reduce((prev, item) => (prev += `${item}=${params[item]}&`), "")
      .slice(0, -1);

  return new Promise((resolve, reject) => {
    let xhr = new XMLHttpRequest();

    if (method == "get" || method === "delete") {
      xhr.open(method, baseUrl + url + "?" + parsePar(params));
      xhr.send();
    } else if (method === "post" || method === "put") {
      xhr.open(method, baseUrl + url);
      xhr.setRequestHeader("content-type", "application/x-www-form-urlencoded");
      xhr.send(parsePar(params));
    }

    xhr.onreadystatechange = function () {
      //这行代码的代码的意义是,将没到4的情况的数据全部拒绝掉
      if (this.readyState != 4) return;
      if (this.readyState === 4 && this.status === 200) {
        resolve(JSON.parse(this.responseText));
      } else {
        reject("请求失败!");
      }
    };
  });
};

image.png 我们使用这个函数的时候,需要传入对象,需要传入url,baseUrl,method,params等参数,如果不传的话就会使用默认参数,这里使用的扩展运算符...来实现。

调用函数后,会得到一个promise对象作为返回值,想要拿到咱们正确返回的值,可以使用.then来拿到,或者使用await。

例如:
// 根据查询参数,然后进行ajax请求,获取当前类别下的演出列表数据
        myAjax({
          baseUrl: "http://ludir.cn/api/webapi/public/index",
          url: "/detailsContent",
          params: {
            did: paramsObj.did,
          },
        }).then(function (res) {
          if (!Array.isArray(res))
            return (list.innerText =
              "很抱歉,当前演出类别暂无数据,小麦麦正在努力获取更多演出信息!");

再例如:(await后面接promise对象,就可以直接拿到resolve返回的内容,记住想这么用必须写async)

image.png