前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >三、基于promise封装属于自己的Ajax库

三、基于promise封装属于自己的Ajax库

作者头像
Dreamy.TZK
发布2020-08-26 22:22:29
7280
发布2020-08-26 22:22:29
举报

分析

实现一个自己的ajax库,那么我们需要有一些配置,用于修改baseURLurl等信息。

let _default = {
    method: "GET",
    url: "",
    baseURL: "",
    headers: {},
    dataType: "JSON",
    data: null, // => post系列请求
    params: null, // => get系列请求基于?传参
    cache: true,
};

接下来便是核心函数,核心函数内处理数据,并且发出请求。

(function anonymous() {
    let ajaxPromise = function ajaxPromise(options) {
        let {
            method,
            url,
            baseURL,
            headers,
            dataType,
            data,
            params,
            cache,
        } = options;
       // 处理参数
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest();
            // URL地址
            xhr.open(method, `${baseURL}${url}`);
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (/^2|3\d{2}/.test(xhr.status)) {
                        // 如果请求成功,则返回结果
                        resolve(result);
                        return;
                    }
                    // 请求失败抛出异常
                    reject(xhr.status);
                }
            };
            // 发送的数据
            xhr.send(data);
        });
    };
}

最重要的就是发送数据前对传入数据的处理。首先判断根据请求方式处理需要传入的参数。

(function anonymous() {
    let ajaxPromise = function ajaxPromise(options) {
        let {
            method,
            url,
            baseURL,
            headers,
            dataType,
            data,
            params,
            cache,
        } = options;
        // 处理参数
        if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
            //   GET系列
            if (params) {
                url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
            }
            if (cache === false) {
                url += `${ajaxPromise.check(url)}_=${+new Date()}`;
            }
            data = null;
        } else {
            //   POST系列
            if (data) {
                data = ajaxPromise.formatData(data);
            }
        }
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest();
            // URL地址
            xhr.open(method, `${baseURL}${url}`);
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (/^2|3\d{2}/.test(xhr.status)) {
                        // 如果请求成功,则返回结果
                        resolve(result);
                        return;
                    }
                    // 请求失败抛出异常
                    reject(xhr.status);
                }
            };
            // 发送的数据
            xhr.send(data);
        });
    };
    // 将对象变成urlencoded字符串
    ajaxPromise.formatData = function formatData(obj) {
        let str = ``;
        for (let attr in obj) {
            if (obj.hasOwnProperty(attr)) {
                str += `${attr}=${obj[attr]}&`;
            }
        }
        return str.substring(0, str.length - 1);
    };
    ajaxPromise.defaults = _default;
}

接下来处理的是发出请求时,请求头的一些配置

(function anonymous() {
    let ajaxPromise = function ajaxPromise(options) {
        let {
            method,
            url,
            baseURL,
            headers,
            dataType,
            data,
            params,
            cache,
        } = options;
        // 处理参数
        if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
            //   GET系列
            if (params) {
                url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
            }
            if (cache === false) {
                url += `${ajaxPromise.check(url)}_=${+new Date()}`;
            }
            data = null;
        } else {
            //   POST系列
            if (data) {
                data = ajaxPromise.formatData(data);
            }
        }
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest();
            // URL地址
            xhr.open(method, `${baseURL}${url}`);
            if (headers !== null && typeof headers === "object") {
                for (let attr in headers) {
                    if (headers.hasOwnProperty(attr)) {
                        //   处理中文
                        let val = headers[attr];
                        if (/[\u4e00-\u9fa5]/.test(val)) {
                            // 将中文进行编码
                            val = encodeURIComponent(val);
                        }
                        xhr.setRequestHeader(attr, headers[attr]);
                    }
                }
            }
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (/^2|3\d{2}/.test(xhr.status)) {
                        // 如果请求成功,则返回结果
                        resolve(result);
                        return;
                    }
                    // 请求失败抛出异常
                    reject(xhr.status);
                }
            };
            // 发送的数据
            xhr.send(data);
        });
    };
    // 将对象变成urlencoded字符串
    ajaxPromise.formatData = function formatData(obj) {
        let str = ``;
        for (let attr in obj) {
            if (obj.hasOwnProperty(attr)) {
                str += `${attr}=${obj[attr]}&`;
            }
        }
        return str.substring(0, str.length - 1);
    };
    ajaxPromise.defaults = _default;
}

在然后就是处理当请求发出去,将结果进行返回

(function anonymous() {
    let ajaxPromise = function ajaxPromise(options) {
        let {
            method,
            url,
            baseURL,
            headers,
            dataType,
            data,
            params,
            cache,
        } = options;
        // 处理参数
        if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
            //   GET系列
            if (params) {
                url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
            }
            if (cache === false) {
                url += `${ajaxPromise.check(url)}_=${+new Date()}`;
            }
            data = null;
        } else {
            //   POST系列
            if (data) {
                data = ajaxPromise.formatData(data);
            }
        }
        return new Promise((resolve, reject) => {
            let xhr = new XMLHttpRequest();
            // URL地址
            xhr.open(method, `${baseURL}${url}`);
            if (headers !== null && typeof headers === "object") {
                for (let attr in headers) {
                    if (headers.hasOwnProperty(attr)) {
                        //   处理中文
                        let val = headers[attr];
                        if (/[\u4e00-\u9fa5]/.test(val)) {
                            // 将中文进行编码
                            val = encodeURIComponent(val);
                        }
                        xhr.setRequestHeader(attr, headers[attr]);
                    }
                }
            }
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (/^2|3\d{2}/.test(xhr.status)) {
                        let result = xhr.responseText;
                        dataType.toUpperCase();
                        dataType === "JSON"
                            ? (result = JSON.parse(result))
                        : dataType === "XML"
                            ? (result = xhr.responseXML)
                        : null;
                        resolve(result);
                        return;
                    }
                    reject(xhr.status);
                }
            };
            // 发送的数据
            xhr.send(data);
        });
    };
    // 将对象变成urlencoded字符串
    ajaxPromise.formatData = function formatData(obj) {
        let str = ``;
        for (let attr in obj) {
            if (obj.hasOwnProperty(attr)) {
                str += `${attr}=${obj[attr]}&`;
            }
        }
        return str.substring(0, str.length - 1);
    };
    ajaxPromise.defaults = _default;
}

最后,只需要将方法暴露即可。

(function anonymous() {
  let _default = {
    method: "GET",
    url: "",
    baseURL: "",
    headers: {},
    dataType: "JSON",
    data: null, // => post系列请求
    params: null, // => get系列请求基于?传参
    cache: true,
  };
  let ajaxPromise = function ajaxPromise(options) {
    let {
      method,
      url,
      baseURL,
      headers,
      dataType,
      data,
      params,
      cache,
    } = options;
    //   处理参数
    if (/^(GET|DELETE|HEAD|OPTIONS)$/i.test(method)) {
      //   GET系列
      if (params) {
        url += `${ajaxPromise.check(url)}${ajaxPromise.formatData(params)}`;
      }
      if (cache === false) {
        url += `${ajaxPromise.check(url)}_=${+new Date()}`;
      }
      data = null;
    } else {
      //   POST系列
      if (data) {
        data = ajaxPromise.formatData(data);
      }
    }
    return new Promise((resolve, reject) => {
      let xhr = new XMLHttpRequest();
      xhr.open(method, `${baseURL}${url}`);
      if (headers !== null && typeof headers === "object") {
        for (let attr in headers) {
          if (headers.hasOwnProperty(attr)) {
            //   处理中文
            let val = headers[attr];
            if (/[\u4e00-\u9fa5]/.test(val)) {
              // 将中文进行编码
              val = encodeURIComponent(val);
            }
            xhr.setRequestHeader(attr, headers[attr]);
          }
        }
      }
      xhr.onreadystatechange = () => {
        if (xhr.readyState === 4) {
          if (/^2|3\d{2}/.test(xhr.status)) {
            let result = xhr.responseText;
            dataType.toUpperCase();
            dataType === "JSON"
              ? (result = JSON.parse(result))
              : dataType === "XML"
              ? (result = xhr.responseXML)
              : null;
            resolve(result);
            return;
          }
          reject(xhr.status);
        }
      };
      xhr.send(data);
    });
  };
  // 将对象变成urlencoded字符串
  ajaxPromise.formatData = function formatData(obj) {
    let str = ``;
    for (let attr in obj) {
      if (obj.hasOwnProperty(attr)) {
        str += `${attr}=${obj[attr]}&`;
      }
    }
    return str.substring(0, str.length - 1);
  };
  ajaxPromise.defaults = _default;
  ajaxPromise.check = function check(url) {
    return url.indexOf("?") < -1 ? "&" : "?";
  };
  // => get
  ["get", "delete", "head", "options"].forEach((item) => {
    ajaxPromise[item] = function anonymous(url, options = {}) {
      options = {
        ..._default, // => 默认值或者基于defaults修改的值
        ...options, // => 用户调取方法传递的配置项
        url: url, // => 请求的url地址(第一个参数:默认配置项和传递的配置项不会出现url)
        method: item.toUpperCase(),
      };
      return ajaxPromise(options);
    };
  });

  // => POST
  ["post", "put", "patch"].forEach((item) => {
    ajaxPromise[item] = function anonymous(url, data = {}, options = {}) {
      options = {
        ..._default,
        ...options,
        url: url,
        method: item.toUpperCase(),
        data: data,
      };
      return ajaxPromise(options);
    };
  });

  ajaxPromise.post = function (url, data, options) {};
  window.ajaxPromise = ajaxPromise;
})(window);
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档