1. 程式人生 > >從零開始學 Web 之 Ajax(五)同步異步請求,數據格式

從零開始學 Web 之 Ajax(五)同步異步請求,數據格式

遊記 document 空閑 name center 20px 實現 resp 也會

大家好,這裏是「 從零開始學 Web 系列教程 」,並在下列地址同步更新......

  • github:https://github.com/Daotin/Web
  • 微信公眾號:Web前端之巔
  • 博客園:http://www.cnblogs.com/lvonve/
  • CSDN:https://blog.csdn.net/lvonve/

在這裏我會從 Web 前端零基礎開始,一步步學習 Web 相關的知識點,期間也會分享一些好玩的項目。現在就讓我們一起進入 Web 前端學習的冒險之旅吧!

技術分享圖片

一、同步請求與異步請求

同步請求:在用戶進行請求發送之後,瀏覽器會一直等待服務器的數據返回,如果網絡延遲比較高,瀏覽器就一直卡在當前界面,直到服務器返回數據才可進行其他操作。

異步請求:在用戶進行請求發送之後,瀏覽器可以自由操作頁面中其他的元素,當服務器放回數據的時候,才觸發相應事件,對返回的數據進行操作。

如果將 Ajax 請求改為同步請求的話:

1、界面會卡頓,卡頓事件取決於網絡速度;

2、xhr.onreadystatechange 的回調函數不會執行,因為在 xhr.send() 之後,xhr.readyState 就為 4 了,所以數據的處理,直接跟在xhr.send() 之後就可以了。

1、異步的底層原理

js 中的異步實現原理是單線程+事件隊列。js 的代碼執行是單線程的,單線程的意思是代碼從上到下按照順序執行,而事件隊列存儲了一些回調函數,當 js 從上往下執行的時候,遇到回調函數就將其放到事件隊列,在所有 js 代碼執行完成之後處於空閑狀態時,才會去事件隊列看有沒有回調函數達到觸發條件,有的話就執行,沒有的話就繼續閑著。

Ajax 的四步操作中,同步和異步的區別:

如果是異步請求,在 send 的時候,會調用瀏覽器進行網絡數據的請求,send 就執行完了,接著將第四步的回調函數存儲在事件隊列裏面,瀏覽器數據請求完了,readyState 狀態發生變化,觸發第四步回調函數的執行。

而在同步請求中, send 時是自己進行網絡數據的請求,這個時候非得請求到數據,才會接著將第四步的回調函數存儲在事件隊列裏面,所以如果網絡延時頁面就會卡死,在 send 過後接受到數據的時候 readyState 已經為4了,不會再變化,所以第四步的回調函數不會執行。

二、數據格式

什麽是數據格式?

數據格式就是通過一定的規範組織起來,叫做數據格式。

1、XML 數據格式

XML 數據格式是將數據以標簽的方式進行組裝,必須以 <? xml version="1.0" encoding="utf-8" ?> 開頭,標簽必須成對出現,也就是有開始標簽就一定要有結束標簽。

<? xml version="1.0" encoding="utf-8" ?>
<students>
    <student>
      <name>張三</name>
      <age>18</age>
      <sex>男</sex>
  </student>
</students>

缺點:體積太大,元數據(描述數據的數據)太多,解析不方便,目前使用很少。

2、json 數據格式

json 數據格式通過 key-value 的方式組裝。

{
  "student" : [
    {
      "name": "張三",
      "age": "18",
      "sex": "男"
    },
    {
      "name": "李四",
      "age": "23",
      "sex": "女"
    }
  ]
}

優點:體積小,傳輸快,解析方便。

3、案例:獲取圖書信息

接口文檔:

地址 /server/getBooks/php
作用描述 獲取圖書信息
請求類型 get 請求
參數
返回數據格式 xml 格式
返回數據說明 如下
<?xml version="1.0" encoding="utf-8" ?>
<booklist>
    <book>
        <name>三國演義</name>
        <author>羅貫中</author>
        <desc>一個殺伐紛爭的年代</desc>
    </book>
    
    <book>
        <name>水滸傳</name>
        <author>施耐庵</author>
        <desc>108條好漢的故事</desc>
    </book>
    
    <book>
        <name>西遊記</name>
        <author>吳承恩</author>
        <desc>佛教與道教鬥爭</desc>
    </book>
    
    <book>
        <name>紅樓夢</name>
        <author>曹雪芹</author>
        <desc>一個封建王朝的縮影</desc>
    </book>
</booklist>

源代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>書籍列表</title>
    <style>
        div{
            width: 800px;
            margin: 20px auto;
        }
        table{
            width: 800px;
            margin: 20px auto;
            border-collapse: collapse;
        }
        th{
            background-color: #0094ff;
            color:white;
            font-size: 16px;
            padding: 5px;
            text-align: center;
            border: 1px solid black;
        }
        td{
            padding: 5px;
            text-align: center;
            border: 1px solid black;
        }
    </style>
    <script>
        window.onload = function () {  
            var xhr = new XMLHttpRequest();
            xhr.open("get", "./server/getBooks.php", true);
            xhr.send(null);
            xhr.onreadystatechange = function () {  
                if(this.readyState == 4) {
                    if(this.status = 200) {
                        var booklists = this.responseXML.getElementsByTagName("booklist")[0].getElementsByTagName("book");
                        
                        for(var i=0; i<booklists.length; i++) {
                            var name = booklists[i].getElementsByTagName("name")[0].textContent;
                            var author = booklists[i].getElementsByTagName("author")[0].textContent;
                            var desc = booklists[i].getElementsByTagName("desc")[0].textContent;

                            var trObj = document.createElement("tr");
                            trObj.innerHTML = "<td>"+name+"</td><td>"+author+"</td><td>"+desc+"</td>";
                            document.getElementsByTagName("table")[0].appendChild(trObj);
                        }
                    }
                }
            };


        };
    </script>
</head>
<body>
    <div>
        <table>
            <tr>
                <th>書名</th>
                <th>作者</th>
                <th>描述</th>
            </tr>
            <!-- <tr>
                <td>三國演義</td>
                <td>羅貫中</td>
                <td>一個殺伐紛爭的年代</td>
            </tr> -->
        </table>
    </div>
</body>
</html>

XML 數據的格式主要是通過:getElementsByTagName 來獲取的。

4、案例:獲取學生信息

接口文檔:

地址 /server/getStudents/php
作用描述 獲取學生信息
請求類型 get 請求
參數
返回數據格式 json 格式
返回數據說明 如下
[
  {
    "name":"張三",
    "age":"18",
    "sex":"男"
  }
]

源代碼:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>學生列表</title>
    <style>
        div{
            width: 800px;
            margin: 20px auto;
        }
        table{
            width: 800px;
            margin: 20px auto;
            border-collapse: collapse;
        }
        th{
            background-color: #0094ff;
            color:white;
            font-size: 16px;
            padding: 5px;
            text-align: center;
            border: 1px solid black;
        }
        td{
            padding: 5px;
            text-align: center;
            border: 1px solid black;
        }
    </style>
    <script>
        window.onload = function () {  
            var xhr = new XMLHttpRequest();
            xhr.open("get", "./server/getStudents.php", true);
            xhr.send(null);
            xhr.onreadystatechange = function () {  
                if(this.readyState == 4) {
                    if(this.status = 200) {
                        var jsonObj = JSON.parse(this.responseText);
                        for(var i=0; i<jsonObj.length; i++) {
                            var name = jsonObj[i].name;
                            var age = jsonObj[i].age;
                            var sex = jsonObj[i].sex;

                            var trObj = document.createElement("tr");
                            trObj.innerHTML = "<td>"+name+"</td><td>"+age+"</td><td>"+sex+"</td>";
                            document.getElementsByTagName("table")[0].appendChild(trObj);
                        }
                    }
                }
            };
        };
    </script>
</head>
<body>
    <div>
        <table>
            <tr>
                <th>姓名</th>
                <th>年齡</th>
                <th>性別</th>
            </tr>
            <!-- <tr>
                <td>張三</td>
                <td>20</td>
                <td>男</td>
            </tr> -->
        </table>
    </div>
</body>
</html>

只需要將獲取的 responseText 轉化為 json 格式的對象,使用JSON.parse(this.responseText);

技術分享圖片

從零開始學 Web 之 Ajax(五)同步異步請求,數據格式