当前位置: 首页 > article >正文

前端前置——ajax

Day1

目标:使用axios库,获取省份列表数据,展示到页面上

axios库地址:https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js

省份数据地址:http://hmajax.itheima.net/api/province 

axios的使用

axios({

        url:'目标资源地址'   

 }).then(result)=>{

//对服务器返回的数据做后续处理

 })

url告诉axios去哪个地址进行数据交互;result回调函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p class="my-p"></p>
    
    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
    
    <script>
        axios({
            url:'http://hmajax.itheima.net/api/province'
        }).then(result => {
            // console.log(result.data.list)
            //js中 join方法用于把数组中的所有元素放入一个字符串; 元素是通过指定的分隔符进行分隔的
            document.querySelector(".my-p").innerHTML = result.data.list.join('<br>')
        })
    </script>
</body>
</html>
axios — 查询参数

语法:使用axios提供的params选项

axios({

        url:'目标资源地址',

        params:{

                参数名:值

        }

}).then(result => {

//对服务器返回的数据做后续处理

})

这里axios在运行时会把参数名和值拼接到url?参数名=值

常用请求方法

GET:获取数据

POST:提交数据

PUT:修改全部数据

DELETE:删除数据

axios请求配置

url:请求的URL网址

method:请求的方法;其中GET可省

data:提交的数据

获取数据和提交数据的区分

获取数据:

axios({

        url:'目标资源地址',

        method:'get',

        params:{

                参数名:值

        }

})

提交数据:

axios({

        url:'目标资源地址',

        method:'post',

        data:{

                参数名:值

        }

})

axios中的错误处理 

场景:再次注册相同的账号,会遇到报错信息

需求:使用axios错误处理语法,拿到报错信息,弹框反馈给用户

语法:

axios({

}).then(result => {

        //处理数据(成功的结果对象)

}).catch(error => {

        //处理错误(失败的结果对象)

})

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="btn">注册用户</button>

    <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

    <script>
        document.querySelector('.btn').addEventListener('click',()=>{
            axios({
                url:'http://hmajax.itheima.net/api/register',
                method:'post',
                data:{
                    username:'itheima009',
                    password:'76543210'
                }
            }).then(result=>{
                // console.log(result.data.message)
                alert(result.data.message)
            }).catch(error=>{
                // console.log(error.response.data.message)
                alert(error.response.data.message)
            })
        })
    </script>
</body>
</html>
HTTP协议 — 请求报文

组成:

通过浏览器的网络面板中查看请求报文

请求行

请求头

请求体 —— 看请求载荷

HTTP协议 — 响应报文

组成:

响应行

响应状态码:

1~:信息;2~:成功;3~:重定向消息;4~:客户端(浏览器)错误;5~:服务端错误

响应头

响应体 —— 看响应

form-serialize插件

作用:快速收集表单元素的值;一步到位

引入到自己网页中:npm install form-serialize

    <script src="./node_modules/form-serialize/index.js"></script>

语法:

const form = document.querySelector('.example-form')

const data = serialize(form , {hash:true,empty:true} )

                                 传表单对象   配置对象

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form action="javascript:;" class="example-form">
        <input type="text" name="uname">
        <br>
        <input type="text" name="pwd">
        <br>
        <input type="button" class="btn" value="提交">
    </form>

    <script src="./node_modules/form-serialize/index.js"></script>


    <script>
        document.querySelector('.btn').addEventListener('click',()=>{
            const form = document.querySelector('.example-form')
            // 参1:获取哪个表单的数据;表单元素设置name属性,值会作为对象的属性名;属性值最好和接口文档参数名一致
            // 参2:配置对象;
            // hash 设置获取数据结构
            //   -true : js对象
            //   -false : 查询字符串 eg.uname=2345t&pwd=edfgh
            // empty 设置是否获取空值
            //   -true : 获取空值
            //   -false : 不获取空值
            const data = serialize(form,{hash:false,empty:true})
            console.log(data)
        })
    </script>
</body>
</html>

Day2

Bootstrap弹框
通过属性方式,控制弹框的显示隐藏

不离开当前页面,显示单独内容

  • 先引入bootstrap.css和bootstrap.js

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script> 

  • 准备弹框标签

  • 控制弹框显示和隐藏 

语法: 

<button data-bs-toggle="modal" data-bs-target="css选择器">显示弹框</button>

data-bs-toggle="modal":告诉按钮点击后会出来model类型的弹框

<div class="modal form-modal" tabindex="-1">

data-bs-target=".form-modal":一个网页可能有多个弹框,告诉按钮点击对应控制哪个弹框

<div class="modal form-modal" tabindex="-1">

<button data-bs-dismiss="modal">Close</button>

data-bs-dismiss="modal":隐藏当前提示框

<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>

<!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet"> 
    <style>
        .btn-primary{
            display:inline;
        }
    </style>
</head>
<body>
    <button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target=".form-modal">
        显示弹框
    </button>

    <!-- 弹框标签 -->
    <div class="modal form-modal" tabindex="-1">
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <h5 class="modal-title">Modal title</h5>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
              <p>Modal body text goes here.</p>
            </div>
            <div class="modal-footer">
              <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
              <button type="button" class="btn btn-primary">Save changes</button>
            </div>
          </div>
        </div>
      </div>


    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>

</body>
</html>
通过js代码方式,控制弹框的显示隐藏 
  • 同样的引入bootstrap.css和bootstrap.js

<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">

<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script> 

  • 创建弹框对象

const modalDom = document.querySelector('css选择器')

const modal = new bootstrap.Modal(modalDom)

  • 调用弹框对象内置方法

//显示弹框

modal.show()

//隐藏弹框

modal.hide()

<!DOCTYPE html>
<html lang="en">
<head>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet">
    <style>
        .btn-primary{
            display:inline
        }
    </style>
</head>
<body>
    <button type="button" class="btn btn-primary edit-btn">
        编辑姓名
    </button>

    <div class="modal name-box"  tabindex="-1">
        <div class="modal-dialog">
          <div class="modal-content">
            <div class="modal-header">
              <h1 class="modal-title">请输入姓名:</h1>
              <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>

            <div class="modal-body">
              <form action="">
                <span>姓名:</span>
                <input type="text" class="username">
              </form>
            </div>

            <div class="modal-footer">
              <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">取消</button>
              <button type="button" class="btn btn-primary save-btn">保存</button>
            </div>
          </div>
        </div>
      </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/js/bootstrap.min.js"></script>

    <script>
        //1.创建弹框对象
        const modalDom = document.querySelector('.name-box')
        const modal = new bootstrap.Modal(modalDom)
        // 2.编辑姓名

        document.querySelector('.edit-btn').addEventListener('click',()=>{
            //2.1显示弹框
            document.querySelector('.username').value = '默认姓名'
            modal.show()
        })

        document.querySelector('.save-btn').addEventListener('click',()=>{
            const username = document.querySelector('.username').value
            console.log('模拟把姓名保存到服务器上'+ username)
            //2.2隐藏弹框
            modal.hide()
        })

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

Day3

XHR的使用

目标:使用XHR对象与服务器通信;获取省份列表数据,展示到页面上

  • 创建XHR对象

let xhr = new XMLHttpRequest()

  • 调用open方法,设置url和请求方法

xhr.open('请求方法','请求url网址')

  • 监听loadend事件,接受结果

xhr.addEventListener('loadend',() => {

        //响应结果

        console.log(xhr.response)

})

  • 调用send方法,发起请求

xhr.send()

<!DOCTYPE html>
<html lang="en">
<head>
   
</head>
<body>
    <script>
        let xhr = new XMLHttpRequest()
        xhr.open('GET','http://hmajax.itheima.net/api/province')
        xhr.addEventListener('loadend',()=>{
            console.log(xhr.response)
        })
        xhr.send()
    </script>
</body>
</html>

<!DOCTYPE html>
<html lang="en">
<head>
   
</head>
<body>
    <p class="my-p"></p>
    <script>
        let xhr = new XMLHttpRequest()
        xhr.open('GET','http://hmajax.itheima.net/api/province')
        xhr.addEventListener('loadend',()=>{
            // console.log(xhr.response)
            // JSON字符串转对象(不然.list获取不到)
            let data = JSON.parse(xhr.response)
            console.log(data.list.join('<br>'))
            document.querySelector('.my-p').innerHTML = data.list.join('<br>')
        })
        xhr.send()
    </script>
</body>
</html>
XHR — 查询参数

语法:http://xxx.com/xxx/xxx?参数名1=值1&参数名2=值2

目标:使用XHR携带查询参数,展示某个省下属的城市列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p class="city-p"></p>
    <script>
        let xhr = new XMLHttpRequest()
        xhr.open('GET','http://hmajax.itheima.net/api/city?pname=辽宁省')
        xhr.addEventListener('loadend',()=>{
            // console.log(xhr.response)
            let data = JSON.parse(xhr.response)
            console.log(data.list.join('<br>'))
            document.querySelector('.city-p').innerHTML = data.list.join('<br>')
        })
        xhr.send()
    </script>
</body>
</html>

XHR — 数据提交(到服务器保存)

目标:通过XHR提交用户名和密码,完成注册功能

  • 创建XHR对象

let xhr = new XMLHttpRequest()

  • 调用open方法,设置url和请求方法

xhr.open('请求方法','请求url网址')

  • 监听loadend事件,接受结果

xhr.addEventListener('loadend',() => {

        //响应结果

        console.log(xhr.response)

})

  • 设置请求头(eg.设置Content-Type: application/json)

xhr.setRequestHeader('Content-Type','application/json')

  • 准备请求体数据

let userobj = {

 username: 'itheima007',

 password: '7654321'

}

//对象转JSON字符串

const userStr = JSON.stringify(userObj)

  • 调用send方法,发起请求体数据

xhr.send(userStr)

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="reg-btn">注册用户</button>
    <script>
        document.querySelector('.reg-btn').addEventListener('click',()=>{
            let xhr = new XMLHttpRequest()
            xhr.open('POST','http://hmajax.itheima.net/api/register')
            xhr.addEventListener('loadend',()=>{
                console.log(xhr.response)
            })
            //设置请求头
            xhr.setRequestHeader('Content-Type','application/json')
            //准备提交的数据
            const userObj = {
                username:'itheima007',
                password: '7654321'
            }
            const userStr = JSON.stringify(userObj)
            xhr.send(userStr)
        })
       
    </script>
</body>
</html>

Promise 

管理一个异步操作 最终状态(成功或失败) 及其 结果值 的对象

为什么要学Promise —— 成功和失败状态可以关联对应处理程序

  • 创建Promise对象

const p = new Promise((resolve,reject) => {

  • 执行异步任务 并传递结果

成功调用:resolve(值) —— 触发then()执行

失败调用:resolve(值) —— 触发then()执行

})

  • 接收结果

p.then(result => {

//成功

}).catch(error => {

//失败

})

目标:使用Promise管理异步任务

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //1.创建Promise对象 
        const p = new Promise((resolve,reject)=>{
            // 2.执行异步代码 2s
            setTimeout(()=>{
                // resolve('模拟AJAX请求-成功结果')
                reject(new Error('模拟AJAX请求-失败结果'))
            },2000)
        })

        // console.log('1')
        
        //3.获取结果
        p.then(result =>{
            //成功结果
            console.log(result)
        }).catch(error =>{
            //失败结果
            console.log(error)
        })
    </script>
</body>
</html>
Promise的三种状态

一个Promise对象,必然处于以下几种状态之一(pending待定、fulfilled已兑现、rejected已拒绝)

🔺Promise对象一旦被兑现或拒绝,这个状态就不会再改变了

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        //1.创建Promise对象 (pending待定状态)
        const p = new Promise((resolve,reject)=>{
            //Promise对象创建时,这里的代码都会执行了
            //console.log('Promise对象内开始执行')
            //2.执行异步代码
            setTimeout(()=>{
                // fulfilled状态
                resolve('模拟AJAX请求-成功结果')
                // rejected状态
                // reject(new Error('模拟AJAX请求-失败结果'))
            },2000)
        })

        console.log(p)
        
        //3.获取结果
        p.then(result =>{
            //成功结果
            console.log(result)
        }).catch(error =>{
            //失败结果
            console.log(error)
        })
    </script>
</body>
</html>

使用Promise + XHR 获取省份列表
  • 创建Promise对象

const p = new Promise((resolve,reject) => {

  • 执行XHR异步代码

const xhr = new XMLHttpRequest()

xhr.open('请求方法','请求url网址')

xhr.addEventListener('loadend',()=>{

//成功调用

resolve(值)

//失败调用

reject(值)

})

xhr.send()

})

  • 关联成功或失败函数,做后续处理

p.then(result => {

//成功

}).catch(error => {

//失败

})

目标:使用Promise管理XHR请求省份列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p class="my-p"></p>
    <script>
        //1.创建Promise对象 
        const p = new Promise((resolve,reject)=>{
            //2.执行XHR异步代码,获取省份列表
            const xhr = new XMLHttpRequest()
            xhr.open('GET','http://hmajax.itheima.net/api/province123')
            xhr.addEventListener('loadend',()=>{
                //xhr根据状态码判断的响应成功还是失败 —— 2开头的都是成功响应状态码
                if(xhr.status >= 200 && xhr.status < 300){
                    //字符串转对象
                    resolve(JSON.parse(xhr.response))
                }else{
                    reject(new Error(xhr.response))
                }
            })
            xhr.send()
        })
     
        //3.关联成功或失败函数,做后续处理
        p.then(result =>{
            //成功结果
            console.log(result)
            document.querySelector('.my-p').innerHTML = result.list.join('<br>')
        }).catch(error =>{
            //错误对象要用console.dir详细打印
            console.dir(error)
            document.querySelector('.my-p').innerHTML = error.message
        })
    </script>
</body>
</html>

封装 — 简易axios — 获取省份列表

复习:

  • 定义myAxios函数,接收配置对象,返回Promise对象

function myAxios(config){

config配置对象;会有url、method(、params/data)属性

        return new Promise((resolve,reject) => {

  • 发起XHR请求,默认请求为GET

                const xhr = new XMLHttpRequest()

                xhr.open(config.method || 'GET' , config.url)

config.method || 'GET' :axios的method默认请求方法为GET

js中的||:JS中的 || 与 && 运算符详解_js ||-CSDN博客

只要“||”前面为false;不管“||”后面是true还是false,都返回“||”后面的值
只要“||”前面为true;不管“||”后面是true还是false,都返回“||”前面的值

                xhr.addEventListener('loadend' , () => {

  • 调用成功/失败的处理程序

                        if(xhr.status >= 200 && xhr.status < 300){

                                resolve(JSON.parse(xhr.response))

                        }else{

                                reject(new Error(xhr.response))

                        }

                })

                xhr.send()

发起请求

        })

}

  • 使用myAxios函数,获取省份列表展示

myAxios({

        url:'http://hmajax.itheima.net/api/province'

仅需url属性

GET请求,不需要查询参数继而不需要params属性

method这个属性没有;前面config.method的值为undefinded;设置的请求方法就为后面的GET

}).then(result => {

        console.log(result)

}).catch(error => {

        console.log(error)

})

目标:封装 — 简易axios函数 — 获取省份列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p class="my-p"></p>
    <script>
        //1.定义myAxios函数,接收配置对象,返回Promise对象
        function myAxios(config){
            return new Promise((resolve,reject)=>{
                //2.发起XHR请求,默认请求为GET
                const xhr = new XMLHttpRequest()
                xhr.open(config.method || 'GET',config.url)
                xhr.addEventListener('loadend',()=>{
                    //3.调用成功/失败的处理程序
                    if(xhr.status >= 200 && xhr.status < 300){
                        //字符串转对象
                        resolve(JSON.parse(xhr.response))
                    }else{
                        reject(new Error(xhr.response))
                    }
                })
                xhr.send()
            })
        }
     
        //4.使用myAxios函数,获取省份列表展示
        myAxios({
            url:'http://hmajax.itheima.net/api/province'
        }).then(result =>{
            document.querySelector('.my-p').innerHTML = result.list.join('<br>')
        }).catch(error =>{
            document.querySelector('.my-p').innerHTML = error.message
        })
    </script>
</body>
</html>
封装 — 简易axios — 获取地区列表

 function myAxios(config){

            return new Promise((resolve,reject)=>{

                const xhr = new XMLHttpRequest()

  • 判断是否有params选项,如果有的话携带查询参数

为什么要判断呢 —— 这里是封装axios;这个函数调用时不能保证每次都有params选项;可能没有,也可能有的时data

                if(config.params){

  • 使用URLSearchParams转换,并携带到url上

                        const paramsObj = new URLSearchParams(config.params)

URLSearchParams_nodejs urlsearchparams-CSDN博客

                        const queryString = paramsObj.toString()

  • 把查询参数字符串,拼接在url?后面

                        config.url += `?${queryString}`

                } 

                xhr.open(config.method || 'GET',config.url)

                xhr.addEventListener('loadend',()=>{

                    if(xhr.status >= 200 && xhr.status < 300){

                        resolve(JSON.parse(xhr.response))

                    }else{

                        reject(new Error(xhr.response))

                    }

                })

                xhr.send()

            })

        }

  • 使用myAxios函数,获取地区列表展示

myAxios({

            url:'http://hmajax.itheima.net/api/area',

            params:{

                pname:'辽宁省',

                cname:'大连市'

            }

}).then(result =>{

            document.querySelector('.area-p').innerHTML = result.list.join('<br>')

        }).catch(error =>{

            document.querySelector('.area-p').innerHTML = error.message

        })

目标:封装 — 简易axios函数 — 获取地区列表 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <p class="area-p"></p>
    <script>

        function myAxios(config){
            return new Promise((resolve,reject)=>{
                const xhr = new XMLHttpRequest()
                //1.判断是否有params选项,如果有的话携带查询参数
                if(config.params){
                    // 2.使用URLSearchParams转换,并携带到url上
                    const paramsObj = new URLSearchParams(config.params)
                    const queryString = paramsObj.toString()
                    // 把查询参数字符串,拼接在url?后面
                    config.url += `?${queryString}`
                }
                xhr.open(config.method || 'GET',config.url)
                xhr.addEventListener('loadend',()=>{
                    if(xhr.status >= 200 && xhr.status < 300){
                        //字符串转对象
                        resolve(JSON.parse(xhr.response))
                    }else{
                        reject(new Error(xhr.response))
                    }
                })
                xhr.send()
            })
        }
     
        //3.使用myAxios函数,获取地区列表展示
        myAxios({
            url:'http://hmajax.itheima.net/api/area',
            params:{
                pname:'辽宁省',
                cname:'大连市'
            }
        }).then(result =>{
            document.querySelector('.area-p').innerHTML = result.list.join('<br>')
        }).catch(error =>{
            document.querySelector('.area-p').innerHTML = error.message
        })
    </script>
</body>
</html>
封装 — 简易axios — 携带请求体数据

原生XHR

目标:封装 — 简易axios函数 — 注册用户

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <button class="reg-btn">注册用户</button>
    <script>
        function myAxios(config){
            return new Promise((resolve,reject)=>{
                const xhr = new XMLHttpRequest()
                xhr.open(config.method || 'GET',config.url)
                xhr.addEventListener('loadend',()=>{
                    if(xhr.status >= 200 && xhr.status < 300){
                        //字符串转对象
                        resolve(JSON.parse(xhr.response))
                    }else{
                        reject(new Error(xhr.response))
                    }
                })

                //1.判断有data选项,携带请求体
                if(config.data){
                    xhr.setRequestHeader('Content-Type','application/json')
                    //2.对象转JSON字符串,在send中发送
                    const jsonStr = JSON.stringify(config.data)
                    xhr.send(jsonStr)
                }else{
                    //如果没有请求体数据,正常的发起请求
                    xhr.send()
                }
            })
        }
        
        document.querySelector('.reg-btn').addEventListener('click',()=>{
            //3.使用myAxios函数,完成注册用户
            myAxios({
                url:'http://hmajax.itheima.net/api/register',
                method:'POST',
                data:{
                    username:'itheima999',
                    password:'666666'
                }
            }).then(result =>{
                console.log(result)
            }).catch(error =>{
                console.log(error)
            })
        })

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

Day4 

回调函数地狱

何为回调函数地狱?—— 回调函数中嵌套回调函数,并且一直嵌套下去

造成什么问题:可读性差,异常捕获困难,耦合性严重,牵一发动全身

需求:展示默认第一个省,第一个城市,第一个地区在下拉菜单中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form>
        <span>省份:</span>

        <select>
          <option class="province"></option>
        </select>

        <span>城市:</span>

        <select>
          <option class="city"></option>
        </select>

        <span>地区:</span>

        <select>
          <option class="area"></option>
        </select>
      </form>

      <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

      <script>
        //1.获取默认第一个省份的名字
        axios({url:'http://hmajax.itheima.net/api/province'}).then(result => {
            // console.log(result.data.list[0])
            const pname=result.data.list[0]
            document.querySelector('.province').innerHTML = pname
            //2.获取默认第一个城市的名字
            axios({url:'http://hmajax.itheima.net/api/city',params:{pname}}).then(result => {
                const cname=result.data.list[0]
                document.querySelector('.city').innerHTML = cname 
                //3.获取默认第一个地区的名字
                axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}}).then(result => {
                    const areaName = result.data.list[0]
                    document.querySelector('.area').innerHTML = areaName
                })
            })
        })
      </script>

</body>
</html>
Promise —— 链式调用

可以解决回调函数地狱的问题

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form>
        <span>省份:</span>

        <select>
          <option class="province"></option>
        </select>

        <span>城市:</span>

        <select>
          <option class="city"></option>
        </select>

        <span>地区:</span>

        <select>
          <option class="area"></option>
        </select>
      </form>

<script>
    //1.创建Promise对象——模拟请求省份名字
    const p = new Promise((resolve,reject)=>{
        setTimeout(()=>{
            resolve('北京市')
        },2000)
    })

    //2.接收结果;获取省份名字
    const p2 = p.then(result => {
        //箭头函数;函数体内,返回新的Promise对象
        console.log(result)//接收resolve的结果值
        return new Promise((resolve,reject) => {
            setTimeout(() => {
                resolve(result+'--- 北京')
            },2000)
        })
    })

    //4.获取城市名字
    p2.then(result => {
        console.log(result)
    })
</script>
      
</body>
</html>

Promise —— 链式应用

把省、市、区回调函数嵌套问题变成一种线性结构

axios会在原地返回一个Promise对象 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <form>
        <span>省份:</span>

        <select>
          <option class="province"></option>
        </select>

        <span>城市:</span>

        <select>
          <option class="city"></option>
        </select>

        <span>地区:</span>

        <select>
          <option class="area"></option>
        </select>
      </form>

      <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

      <script>
        let pname=''
        //1.得到-获取省份Promise对象;axios调用后在原地会返回一个Promise对象
        axios({url:'http://hmajax.itheima.net/api/province'}).then(result => {
            pname=result.data.list[0]
            document.querySelector('.province').innerHTML = pname
            //2.得到-获取城市的Promise对象
            return axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})  
        }).then(result => {
            const cname=result.data.list[0]
            document.querySelector('.city').innerHTML = cname 
            //3.得到-获取地区的Promise对象
            return axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}})
        }).then(result => {
                const areaName = result.data.list[0]
                document.querySelector('.area').innerHTML = areaName
        })
      </script>
</body>
</html> 
async函数和await 

解决回调函数地域问题

概念:在async函数内,使用await关键字,获取Promise对象“成功状态”结果值

await会阻止“异步函数内”代码继续执行,原地等待结果;变成了同步形式

<!DOCTYPE html>
<html lang="en">
<head>
    
</head>
<body>
    <form>
        <span>省份:</span>

        <select>
          <option class="province"></option>
        </select>

        <span>城市:</span>

        <select>
          <option class="city"></option>
        </select>

        <span>地区:</span>

        <select>
          <option class="area"></option>
        </select>
      </form>

      <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

      <script>
        //1.定义async修饰函数
        async function getData(){
            //2.await等待Promise对象成功的结果
            const pObj = await axios({url:'http://hmajax.itheima.net/api/province'})
            const pname = pObj.data.list[0]
            const cObj = await axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})
            const cname = cObj.data.list[0]
            const aObj = await axios({url:'http://hmajax.itheima.net/api/area',params:{pname,cname}})
            const areaName = aObj.data.list[0]

            document.querySelector('.province').innerHTML = pname
            document.querySelector('.city').innerHTML = cname
            document.querySelector('.area').innerHTML = areaName
        }
        getData()
      </script>
</body>
</html>
async函数和await — 错误捕获

使用:try...catch

语法:

try{

//要执行的代码(捕获可能会产生错误的代码)

如果try里的某行代码报错后,try中剩余的代码不会执行了

} catch(error){

//try里产生错误;立刻将错误信息传给error参数

//try里的代码,如果有错误,直接进入这里执行

}

<!DOCTYPE html>
<html lang="en">
<head>
    
</head>
<body>
    <form>
        <span>省份:</span>

        <select>
          <option class="province"></option>
        </select>

        <span>城市:</span>

        <select>
          <option class="city"></option>
        </select>

        <span>地区:</span>

        <select>
          <option class="area"></option>
        </select>
      </form>

      <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>

      <script>
        
        async function getData(){
            try{
                const pObj = await axios({url:'http://hmajax.itheima.net/api/province'})
                const pname = pObj.data.list[0]
                const cObj = await axios({url:'http://hmajax.itheima.net/api/city',params:{pname}})
                const cname = cObj.data.list[0]
                const aObj = await axios({url:'http://hmajax.itheima.net/api/area1',params:{pname,cname}})
                const areaName = aObj.data.list[0]

                document.querySelector('.province').innerHTML = pname
                document.querySelector('.city').innerHTML = cname
                document.querySelector('.area').innerHTML = areaName
            } catch (error){
                console.dir(error.response.data.message)
            }   
        }
        getData()
      </script>
</body>
</html>


http://www.kler.cn/a/387650.html

相关文章:

  • 【数据结构与算法】第11课—数据结构之选择排序和交换排序
  • 在Java中使用ModelMapper简化Shapefile属性转JavaBean实战
  • Android中桌面小部件的开发流程及常见问题和解决方案
  • 如何用C#和Aspose.PDF实现PDF转Word工具
  • win32 / WTL 开发多线程应用,子线程传递大对象给UI线程(主窗口)的方法
  • 万字长文解读深度学习——ViT、ViLT、DiT
  • 前端递归获取树(不限制层级)结构下的某个字段并组成数组返回
  • WPF 打包
  • Vue前端开发之自定义动画
  • 如何在 Android 14 中调整字体最大 大小 和 显示最大一格 大小
  • 【AI技术】Edge-TTS 国内使用方法
  • 问题排查:C++ exception with description “getrandom“ thrown in the test body
  • Ubuntu实现双击图标运行自己的应用软件
  • Windows系统中Oracle VM VirtualBox的安装
  • 2024年第四届“网鼎杯”网络安全比赛---朱雀组Crypto- WriteUp
  • 计算机网络常见面试题(一):TCP/IP五层模型、TCP三次握手、四次挥手,TCP传输可靠性保障、ARQ协议
  • 个性化培训:扫码分组指南
  • ResNet 残差网络 (乘法→加法的思想 - 残差连接是所有前沿模型的标配) + 代码实现 ——笔记2.16《动手学深度学习》
  • FPGA时序分析和约束学习笔记(4、IO传输模型)
  • Linux命令学习,git命令
  • Node-Red二次开发:各目录结构说明及开发流程
  • Mac intel 安装IDEA激活时遇到问题 jetbrains.vmoptions.plist: Permission denied
  • 量化交易系统开发-实时行情自动化交易-Okex行情交易数据
  • Spark的Standalone集群环境安装
  • arcgis pro 学习笔记
  • 代码随想录算法训练营Day58 | 卡玛网 110.字符串接龙、卡玛网 105.有向图的完全可达性、卡玛网 106.岛屿的周长