【前端】手写JavaScript ajax封装(从青铜到王者)(promise)

前言:话说菩提祖师打了孙猴子三板子 然后悟空学会72般变化以及一身神通 对待这个问题作为面试者要思考更加深层次的意义 才更能获得认可

实际上写的ajax很能看出一个人的水平 贴几段代码就可以看出水平的高低

本篇文章主讲ajax的封装 (默认你已经懂ajax的使用)

一、青铜水平

var req = new XMLHttpRequest();
req.open("get", "mockData/usersinfo.json", true);
req.send();
req.onreadystatechange = function () {
    if (req.readyState == 4 && req.status == 200) {
        var result= req.responseText;
    }
}

\color{red}{特别普通的一段原生ajax 功能也是特别的简单的功能 获取一个模拟的数据 这段代码能反应啥 你可以写出来 也能记住对吧}

二、白银水平

1.封装代码
function ajax(type, url, success) {
    var req = new XMLHttpRequest();
    req.open(type, url, true);
    req.send();
    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
            var result = req.responseText;
            success(result);

        }
    }
}
2.使用方法
ajax("get", "http://localhost:8055/listcount.php?search=a", function (result) {
    alert(result);
});

三、黄金水平

1.封装代码
function ajax(json) {
    var req = new XMLHttpRequest();
    var type = json["type"];
    var url = json["url"];
    if (json["data"]) {
        var html = "?";
        for (var i in json["data"]) {
            html += i + "=" + json["data"][i] + "&";
        }
        html = html.substring(0, html.length - 1);
        url += html;
    }
    var success = json["success"];
    req.open(type, url, true);
    req.send();
    req.onreadystatechange = function () {
        if (req.readyState == 4 && req.status == 200) {
            var result = req.responseText;
            if (json["dataType"] == "json") {
                result = JSON.parse(result);
            }
            success(result);
        }
    }
}
2.使用方法
ajax({
    type: "get",
    url: "http://localhost:8055/listcount.php",
    data: {search: "l"},
    dataType: "json",
    success: function (result) {
        alert(result["count"]);
    }
});

\color{red}{以上代码功能也是一样 但是感觉更好了 是不是有一点所谓jq中使用ajax的感觉了 此刻可以啦啦啦的 跳个舞了 千万不要满足}

四、钻石水平

1.封装代码
var $ = {
    ajax: function (json) {
        var req = new XMLHttpRequest();
        var type = json["type"];
        var url = json["url"];
        if (json["data"]) {
            var html = "?";
            for (var i in json["data"]) {
                html += i + "=" + json["data"][i] + "&";
            }
            html = html.substring(0, html.length - 1);
            url += html;
        }
        var success = json["success"];
        req.open(type, url, true);
        req.send();
        req.onreadystatechange = function () {
            if (req.readyState == 4 && req.status == 200) {
                var result = req.responseText;
                if (json["dataType"] == "json") {
                    result = JSON.parse(result);
                }
                success(result);
            }
        }
    }
}
2.使用方法
$.ajax({
    type: "get",
    url: "http://localhost:8055/listcount.php",
    data: {search: "l"},
    dataType: "json",
    success: function (result) {
        alert(result["count"]);
    }
});

\color{red}{怎么样 虽然写的是原生ajax 但是写出了jq底层代码的味道 跟jq中使用方式一模一样 参数 回调 封装 面面俱到 水平高低 一看就知道了 自己都会写 工作肯定也就会用 这才是钻石水平}

五、王者水平(promise)

ps:此版本的封装 仅讲解vue的使用方法

1.首先新建js文件封装好代码 别忘记导出
class XHR {

    constructor() {
        this.Url = 'http://0.0.0.0:0000';
    }

    async get(url) {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.crossDomain = true;
            xhr.withCredentials = true;
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && (xhr.status < 300 || xhr.status === 304)) {
                        if (xhr.responseText) {
                            resolve(JSON.parse(xhr.responseText));
                        } else {
                            resolve(xhr.responseText);
                        }
                    } else {
                        reject(`XHR unsuccessful:${xhr.status}`);
                    }
                }
            };

            xhr.open('get', this.Url + url, true);
            xhr.send(null);
        });
    }

    async post(url, data) {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.withCredentials = true;
            xhr.crossDomain = true;
            xhr.onreadystatechange = () => {
                if (xhr.readyState === 4) {
                    if (xhr.status >= 200 && (xhr.status < 300 || xhr.status === 304)) {
                        resolve(JSON.parse(xhr.responseText));
                    } else {
                        reject(`XHR unsuccessful:${xhr.status}`);
                    }
                }
            };
            xhr.open('post', this.Url + url, true);
            xhr.setRequestHeader('content-type', 'application/json');
            xhr.send(JSON.stringify(data));
        });
    }

  
}
export default new XHR();
2.其次在main.js入口文件中引入
import Http from '@/api/Http.js';

Vue.prototype.$Http = Http;
3.最后是使用方法(post可直接替换为get)
this.$Http.post("/viewmember", {
    userId: userId
}).then(res => {
     console.log(res)            
});
有人也许会说既然都promise了 为什么还要加async 这个为大家解答一下 以前看到了阮一峰老师的一篇博客就是这样的写法 可能我现在还不能完全深入理解这样的写法 只是一种模仿大佬的写法 大家也可以去掉async

你可能感兴趣的:(【前端】手写JavaScript ajax封装(从青铜到王者)(promise))