AJAX006——异步与同步

发布时间 2023-10-03 07:21:18作者: 猪无名

AJAX的异步与同步

  • 什么是异步?什么是同步?

    • ajax请求1和ajax请求2,同时并发,谁也不用等谁,这就是异步。(a不等b,b也不等a)
    • 如果ajax请求1在发送的时候需要等待ajax请求2结束之后才能发送,那么这就是同步。(a等待b,或者b等待a,只要发生等待,就是同步。)
  • 异步和同步在代码上如何实现?

    // 假设这个是ajax请求1
    // 如果第三个参数是false:这个就表示“ajax请求1”不支持异步,也就是说ajax请求1发送之后,会影响其他ajax请求的发送,只有当我这个请求结束之后,你们其他的ajax请求才能发送。
    // false表示,不支持异步。我这个 请求发了之后,你们其他的请求都要靠边站。都等着。你们别动呢,等我结束了你们再说。
    xhr1.open("请求方式", "URL", false)
    xhr1.send()
    
    // 假设这个是ajax请求2
    // 如果第三个参数是true:这个就表示“ajax请求2”支持异步请求,也就是说ajax请求2发送之后,不影响其他ajax请求的发送。
    xhr2.open("请求方式", "URL", true) 
    xhr2.send()
    12345678910
    
  • 什么情况下用同步?(大部分情况下我们都是使用ajax异步方式,同步很少用。)

    • 举一个例子
      • 用户注册
        • 用户名需要发送ajax请求进行校验。
        • 邮箱地址也需要发送ajax请求校验。
        • 其他的也可能需要发送ajax请求。
        • 并且最终注册按钮的时候,也是发送ajax请求进行注册。
        • 那么显然,注册的Ajax请求和校验的ajax请求不能异步,必须等待所有的校验ajax请求结束之后,注册的ajax请求才能发。

AJAX代码封装

  • AJAX请求相关的代码都是类似的,有很多重复的代码,这些重复的代码能不能不写,能不能封装一个工具类。要发送ajax请求的话,就直接调用这个工具类中的相关函数即可。
  • 接下来,手动封装一个工具类,这个工具类我们可以把它看做是一个JS的库。我们把这个JS库起一个名字,叫做jQuery。(我这里封装的jQuery只是一个前端的库,和后端的java没有关系,只是为了方便web前端代码的编写,提高WEB前端的开发效率)

手写jQuery,源代码

function jQuery(selector){
    
    if (typeof selector == "string") {
        if (selector.charAt(0) == "#") {
            domObj = document.getElementById(selector.substring(1))
            return new jQuery()
        }
    }
    
    if (typeof selector == "function") {
        window.onload = selector
    }
    
    this.html = function(htmlStr){
        domObj.innerHTML = htmlStr
    }
    this.click = function(fun){
        domObj.onclick = fun
    }
    this.focus = function (fun){
        domObj.onfocus = fun
    }
    this.blur = function(fun) {
        domObj.onblur = fun
    }
    this.change = function (fun){
        domObj.onchange = fun
    }
    
    this.val = function(v){
        if (v == undefined) {
            return domObj.value
        }else{
            domObj.value = v
        }
    }

    // 静态的方法,发送ajax请求
    /**
     * 分析:使用ajax函数发送ajax请求的时候,需要程序员给我们传过来什么?
     *      请求的方式(type):GET/POST
     *      请求的URL(url):url
     *      请求时提交的数据(data):data
     *      请求时发送异步请求还是同步请求(async):true表示异步,false表示同步。
     */
    jQuery.ajax = function(jsonArgs){
        // 1.创建XMLHttpRequest对象
        var xhr = new XMLHttpRequest();
        // 2.监听
        xhr.onreadystatechange = function(){
            if (this.readyState == 4) {
                if (this.status == 200) {
                    // 我们这个工具类在封装的时候,先不考虑那么多,假设服务器返回的都是json格式的字符串。
                    var jsonObj = JSON.parse(this.responseText)
                    // 调用函数
                    jsonArgs.success(jsonObj)
                }
            }
        }

        if (jsonArgs.type.toUpperCase() == "POST") {
            // 3.开启通道
            xhr.open("POST", jsonArgs.url, jsonArgs.async)
            // 4.发送数据
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded")
            xhr.send(jsonArgs.data)
        }

        if (jsonArgs.type.toUpperCase() == "GET") {
            xhr.open("GET", jsonArgs.url + "?" + jsonArgs.data, jsonArgs.async)
            xhr.send()
        }
    }
}
$ = jQuery

// 这里有个细节,执行这个目的是为了让静态方法ajax生效。
new jQuery()

js知识点回顾

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    function User(name, age){
        //属性
        this.name = name;
        this.age = age;
        //实例方法,通过对象调用
        this.doSome = function(){
            console.log(this.name + " Do Some");
        }
        //静态方法,通过类调用
        User.doOther = function(){
          console.log(this.name + " Do Other");
        }
    }

    //创建对象,访问对象的属性,访问对象的方法
    var user = new User("Jack", 20);
    console.log(user.name);
    console.log(user.age);
    user.doSome();
    User.doOther();//这行代码执行的前提是var user = new User("Jack", 20);它虽然调用的时候可以直接用类名,但是不创建对象的话,静态方法不生效。

</script>
</body>
</html>

//扩展方法
User.prototype.printUsername = function(){
    console.log(this.name);
}

user.printUsername();

封装后的代码

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<script type="text/javascript">
    
  function jQuery(selector){
      
    if(typeof  selector == "string"){
      if(selector.charAt(0)=="#"){
        domObj = document.getElementById(selector.substring(1));
        return new jQuery();
      }
    }
      
    if(typeof  selector == "function"){
      window.onload = selector;
    }

    //定义一个html方法
    this.html = function(htmlStr){
      domObj.innerHTML = htmlStr;
    }
    //定义一个click函数,代替document的onclick
    this.click = function(fun){
      domObj.onclick = fun;
    }

    //返回文本框的值
    // this.valu= function(){
    //   return domObj.value;
    // }
    // this.setvalu= function(htmlStr){
    //   domObj.value =  htmlStr;
    // }
    //将valu和setvalu方法优化为一个方法
      
    this.valu = function(htmlStr){
      //没有传参,就是要获取参数
      if(htmlStr == undefined){
        return domObj.value;
      }else{//传参就是要修改文本框内容
        domObj.value = htmlStr;
      }
    }
  }
  $ = jQuery;
    
  //使用代码
  $(function (){
    $("#btn").click( function(){
      $("#div1").html("<font color='red'>123556</font>");
      alert($("#name").valu());
      // $("#name").setvalu("已提交");
      $("#name").valu("已提交123");
    })
  })
</script>
用户名:<input type="text" id="name">
<button id = "btn">显示信息</button>
<div id = "div1"></div>
</body>
</html>

代码提取

//封装一个函数,通过这个函数可以获取到html页面的节点,这个函数起名为 jQuery。
function jQuery(selector){

    //通过 #id 的方式来获取元素。
    //document.getElementById(selector.substring(1))  通过截串的方式来获取页面组件的id属性
    //
    if (typeof selector == "string") {
        if (selector.charAt(0) == "#") {
            domObj = document.getElementById(selector.substring(1));
            //返回一个新的对象,之后就可以调用这个对象的方法了。
            return new jQuery();
        }
    }

    if (typeof selector == "function") {
        window.onload = selector;
    }


    this.html = function(htmlStr){
        domObj.innerHTML = htmlStr;
    }
    this.click = function(fun){
        domObj.onclick = fun;
    }
    this.focus = function (fun){
        domObj.onfocus = fun;
    }
    this.blur = function(fun) {
        domObj.onblur = fun;
    }
    this.change = function (fun){
        domObj.onchange = fun;
    }
    this.val = function(v){
        if (v == undefined) {
            return domObj.value;
        }else{
            domObj.value = v;
        }
    }

    // 静态的方法,发送ajax请求
    /**
     * 分析:使用ajax函数发送ajax请求的时候,需要程序员给我们传过来什么?
     *      请求的方式(type):GET/POST
     *      请求的URL(url):url
     *      请求时提交的数据(data):data
     *      请求时发送异步请求还是同步请求(async):true表示异步,false表示同步。
     */

    jQuery.ajax = function(jsonArgs){
        // 1.创建XMLHttpRequest对象
        var xhr = new XMLHttpRequest();
        // 2.监听
        xhr.onreadystatechange = function(){
            if (this.readyState == 4) {
                if (this.status == 200) {
                    // 我们这个工具类在封装的时候,先不考虑那么多,假设服务器返回的都是json格式的字符串。
                    var jsonObj = JSON.parse(this.responseText);
                    // 调用函数
                    jsonArgs.success(jsonObj)
                }
            }
        }

        //判断发送请求的方式是POST还是GET。
        //前端传输的json对象包含的属性 url,data,async。
        if (jsonArgs.type.toUpperCase() == "POST") {
            // 3.开启通道
            xhr.open("POST", jsonArgs.url, jsonArgs.async);
            // 4.发送数据
            xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
            xhr.send(jsonArgs.data);
        }

        if (jsonArgs.type.toUpperCase() == "GET") {
            // 3.开启通道
            xhr.open("GET", jsonArgs.url + "?" + jsonArgs.data, jsonArgs.async);
            // 4.发送数据
            xhr.send();
        }
    }

}

//用 $ 代替 jQuery,简化代码。
$ = jQuery;

// 这里有个细节,执行这个的目的是为了让静态方法ajax生效。
new jQuery();