1.ajax综合案例

本文详细介绍了原生Ajax的使用,包括带参数查询、POST请求,探讨了同步异步与回调函数的概念,深入讲解了回调地狱问题,并通过Promise的语法、状态及面试题,展示了如何用Promise优雅地解决异步问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css">
    <style>
        :root {
            font-size: 15px;
        }

        body {
            padding-top: 15px;
        }
    </style>
</head>

<body >
    <!-- 栅格系统 -->
    <div class="container">
        <div class="d-flex justify-content-between align-items-center">
            <h1>图书管理</h1>
            <button class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#addModal" id="myAddBtn">添加</button>
        </div>
        <table  class="table table-bordered table-striped table-dark table-hover text-center">
            <thead>
                <!-- 表头行 -->
                <tr>
                    <th scope="col">Id</th>
                    <th scope="col">书名</th>
                    <th scope="col">作者</th>
                    <th scope="col">出版社</th>
                    <th scope="col">操作</th>
                </tr>
            </thead>
            <tbody id="tbody">
                <!-- 表格中的每一行 -->
                <tr>
                    <th scope="row">xxx</th>
                    <td>xxx</td>
                    <td>xxx</td>
                    <td>xxx</td>
                    <td>
                        <button type="button" class="btn btn-link btn-sm btn-delete">删除</button>
                        <button type="button" class="btn btn-link btn-sm btn-update">编辑</button>
                    </td>
                </tr>
            </tbody>
        </table>
    </div>
    <!-- add Modal -->
    <div class="modal fade" id="addModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">添加图书</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="addForm"  class="p-3">
                          <!-- 添加name属性名才能使用 serialize  type = 'hidden' 隐藏id属性防止用户修改 -->
                        <!-- 书名 -->
                        <div class="mb-3">
                            <label class="form-label">书名</label>
                            <input type="text" name="bookname" class="form-control" placeholder="请输入图书名称"
                                name="bookname" />
                        </div>
                        <!-- 作者 -->
                        <div class="mb-3">
                            <label class="form-label">作者</label>
                            <input type="text" name="author" class="form-control" placeholder="请输入作者名字" name="author" />
                        </div>
                        <!-- 出版社 -->
                        <div class="mb-3">
                            <label class="form-label">出版社</label>
                            <input type="text" name="publisher" class="form-control" placeholder="请输入出版社名称"
                                name="publisher" />
                        </div>
                    </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" id="addBtn">确认</button>
                </div>
            </div>
        </div>
    </div>
    <!-- edit Modal -->
    <div class="modal fade" id="editModal">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">编辑图书</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body">
                    <form id="editForm" class="p-3">
                        <input type="hidden" name="id" />
                        <!-- 书名 -->
                        <div class="mb-3">
                            <label class="form-label">书名</label>
                            <input type="text" id="bookname" class="form-control" placeholder="请输入图书名称"
                                name="bookname" />
                        </div>
                        <!-- 作者 -->
                        <div class="mb-3">
                            <label class="form-label">作者</label>
                            <input type="text" id="author" class="form-control" placeholder="请输入作者名字" name="author" />
                        </div>
                        <!-- 出版社 -->
                        <div class="mb-3">
                            <label class="form-label">出版社</label>
                            <input type="text" id="publisher" class="form-control" placeholder="请输入出版社名称"
                                name="publisher" />
                        </div>
                    </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" id="editBtn">确认</button>
                </div>
            </div>
        </div>
    </div>
    <script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
    <script src="./lib/form-serialize.js"></script>
    <script>
            // 设置axios的基地址 随后所有的请求URL会自动添加基地址
            axios.defaults.baseURL = 'http://hmajax.itheima.net'
           const addModal = new bootstrap.Modal(document.querySelector('#addModal'))
           const editModal = new bootstrap.Modal(document.querySelector('#editModal'))
            const addForm = document.querySelector('#addForm')
            const editForm = document.querySelector('#editForm')
        // 查找数据   
        function render(){

            // axios({
            //   url:'http://hmajax.itheima.net/api/books',
             
            //   params: {
            //       creater:'刁民'
            //   }
            // })

            // 简写 axios  若参数没有直接里面写地址 axios.get('http://hmajax.itheima.net/api/books')
            axios.get('http://hmajax.itheima.net/api/books',{params:{creater:'刁民'}}).then(res => {
              console.log(res.data.data);
              // 打印的是数组定一个变量接收数组
              let arr = res.data.data
              // 遍历数组
              const str = arr.map(item =>{
                  return `<tr>
                      <th scope="row">${item.author}</th>
                      <td>${item.bookname}</td>
                      <td>${item.creator}</td>
                      <td>${item.publisher}</td>
                      <td>
                          <button  data-id ="${item.id}"type="button" class="btn btn-link btn-sm btn-delete">删除</button>
                          <button data-id ="${item.id}" type="button" class="btn btn-link btn-sm btn-update">编辑</button>
                      </td>
                  </tr>
                  `
              }).join('')
               document.querySelector('#tbody').innerHTML = str
            })
        }
         render()   // 整体思想 把他进行封装函数方便下面调用


         //封装delete 函数
         function deleteBook(id) {
            axios({
                // 要写在if判断里面
            url:'/api/books/'+id,
            method:'DELETE',
          
           })
           .then(res =>{
            console.log(res);
          // 因为删除需要从新渲染结构,所以得调用之前封装好的函数render()
          render()
           })
         }


        // 封装编辑函数
        
        function editBook(id) {
            //alert(1)
            // 显示弹框
            editModal.show()
            axios({
            
            url:'/api/books/' +id,
            method:'GET',
            
           }).then(res =>{
            console.log(res.data.data.bookname);
            
         document.querySelector('#bookname').value = res.data.data.bookname
         document.querySelector('#author').value = res.data.data.author
         editForm.querySelector("[name='id']").value = id

         document.querySelector('#publisher').value = res.data.data.publisher
        
           })
        }
           

      //  删除数据
       // 给tbody注册点击事件 事件委托判断是不是button 按钮 如何查询到当前删除数据 利用自定义属性查找该数据
       // 当我点击删除按钮,自动捕捉到该删除行 在button上加个自定义索引号,自定义属性得用引号包裹起来
        document.querySelector('#tbody').addEventListener('click',(e) => {
            const id = e.target.dataset.id // 索引号
              console.log(id);

            // 要进行if判断选中的按钮时删除还是编辑 因为俩个按钮都是button
           if(e.target.className.includes('btn-delete')) {
            deleteBook(id)
             
           } else if (e.target.className.includes('btn-update')){
             editBook(id)
           }
           // 利用axios访问数据
           
           
        })

        // 新增数据
              //  axios({
              //      url:'http://hmajax.itheima.net/api/books',
              //      method: 'POST',
              //       data: {
              //        bookname:'鸡太美',
              //        author:'蔡徐鸡',
              //        publisher:'小黑社',
              //          creater:'小黑粉'
              //      }
              //    }).then(res => {
              //      console.log(res.data.data);
              //      // 打印的是数组定一个变量接收数组
              //      let arr = res.data.data
              //      // 遍历数组
              //      const str = arr.map(item =>{
              //          return `<tr>
              //              <th scope="row">${item.author}</th>
              //              <td>${item.bookname}</td>
              //              <td>${item.creator}</td>
              //              <td>${item.publisher}</td>
              //              <td>
              //                  <button  data-index ="${item.id}"type="button" class="btn btn-link btn-sm btn-delete">删除</button>
              //                  <button type="button" class="btn btn-link btn-sm btn-update">编辑</button>
              //              </td>
              //          </tr>
              //          `
              //      }).join('')
              //       document.querySelector('#tbody').innerHTML = str
              //    }) 
            
                 // 3 添加案例 注册点击事件
           
            document.querySelector('#addBtn').addEventListener('click',(e) =>{
                const p = serialize(document.querySelector('#addForm'),{hash:true})
                axios({
                    url:'/api/books',
                    method: 'POST',
                    data:p  // 传输的是对象 根据接口文档
                }).then(res => {
                    console.log(res);
                    render()// 重新渲染
                    addModal.hide()
                    addForm.reset()

                })
            })
           
        //  保存编辑结果 给按钮注册点击事件
        //  获取form表单所有数据 用serialize
            document.querySelector('#editBtn').addEventListener('click', (e)=> {
              const p = serialize(document.querySelector('#editForm'),{hash : true })
              console.log(p);
              axios({
                url:'/api/books/' +p.id,
                method:'PUT',
                data:{
                    bookname:p.bookname,
                    author:p.author,
                    publisher:p.publisher
                }
              }).then(res => {
                render()
                editModal.hide()
                console.log(res);
              })
            })
    </script>

2,原生ajax

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1. new 一个 XMLHttpRequest
        const xhr = new XMLHttpRequest()
        // 2. 设置请求方式和地址
        xhr.open('get', 'http://ajax-api.itheima.net/api/province')
        // 3. 发送
        xhr.send()
        // 4. 监听load事件,取到服务器回来的数据
        xhr.addEventListener('load', () => {
            console.log(xhr.response) // JSON字符串
            console.log(JSON.parse(xhr.response))
        })
    </script>
</body>
</html>

3.原生ajax带参数查询

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1. new 一个 XMLHttpRequest
        const xhr = new XMLHttpRequest()
        // 2. 设置请求方式和地址
        // xhr.open('get', 'http://ajax-api.itheima.net/api/city?pname=' + encodeURI('湖北省'))
        // xhr.open('get', 'http://ajax-api.itheima.net/api/city?pname=湖北省')
        xhr.open('get', 'http://ajax-api.itheima.net/api/area?pname=湖北省&cname=武汉市')
        // 3. 发送
        xhr.send()
        // 4. 监听load事件,取到服务器回来的数据
        xhr.addEventListener('load', () => {
            console.log(xhr.response) // JSON字符串
            console.log(JSON.parse(xhr.response))
        })
    </script>
</body>
</html>

4.原生ajax-post

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 1. new XMLHttpRequest
        let xhr = new XMLHttpRequest()
        // 2. 设置请求方式和url
        xhr.open('post', 'http://ajax-api.itheima.net/api/books')

        // 根据接口文档的要求,设置请求头content-type
        xhr.setRequestHeader('content-type', 'application/json')

        // 3. 发送
        // send(请求体的内容)
        const d = {bookname: '书名', author: '作者', publisher: '出版社'}
        xhr.send(JSON.stringify(d))
        // 4. 监听load事件,取到服务器回来的数据
        xhr.addEventListener('load', () => {
            console.log(xhr.response)
        })
    </script>
</body>
</html>

5.同步异步,回调函数

<script src="https://cdn.jsdelivr.net/npm/axios@0.27.2/dist/axios.min.js"></script>
<script>
    console.log(1)
    if (true) {
        console.log(2);
    } else {
        console.log(3);
    }
    setTimeout(() => {
        console.log(4);
    }, 10)
    for (let i = 0; i < 3; i++) {
        console.log(6);
    }   
    const fn = () => {
        console.log(5);
    }
    fn()
    document.addEventListener('click', () => {
        console.log(8);
    })
    
    
    console.log(7);
    axios({
        url: 'http://ajax-api.itheima.net/api/province',
        method: 'GET'
    }).then(() => {
        console.log(9);
    })
    console.log(10);
</script>

6.回调函数

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        document.querySelector('').addEventListener('click', ()=>{})
        // function fn () {
        //     console.log(1)
        // }

        // function t(a){
        //     a()
        // }

        // t(fn)
        // setTimeout(function(){}, 100)
        // setTimeout(fn, 1000)
        const arr = [1,2,3]
        const fn =  (item) => {
            console.log(item)
        }
        arr.forEach(fn) // map, filter, reduce, find, sort ....
    </script>
</body>
</html>

7.回调地狱

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script src="./axios.js"></script>

    <script>
        //  目标:调用接口,请求第6个省的第1个市下的地区列表
        axios.defaults.baseURL = 'http://ajax-api.itheima.net'
        axios.get('/api/province').then(res=>{
            const pname = res.data.data[5]
            console.log(pname)
            axios.get('/api/city?pname='+pname).then(res =>{
                const cname = res.data.data[0]
                console.log(cname)
                axios.get(`/api/area?pname=${pname}&cname=${cname}`).then(res => {
                    console.log(res.data.data)
                })
            })
        })

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

8.promise基本语法

<script>

    // resolve, reject
    // 他们是两个函数,作用分别是
    // resolve(实参) 执行then,实参会给res
    //  reject(实参) 执行catch,实参会给err
    // finally 一定会执行的
    let p1 = new Promise((resolve, reject) => {
        // resolve(100)
        reject(1)
    })

    p1.then(res => {
        console.log('成功', res)
    }).catch(err => {
        console.log('失败', err)
    }).finally(() => {
        console.log('最后一定会执行的')
    })
</script>

9.promise三种状态和值

<script>
    let p1 = new Promise((resolve, reject) => {
        // resolve({a:1}) // [初始]pending ---> [成功]fulfilled ( resolved )
        reject(100) // [初始]pending ---> [失败]rejected
    })

    p1.then(res => {
        console.log(res)
    }).catch(err =>{
        console.log(err)
    })

    console.log(p1)
</script>

10.promise改写异步回调函数

<script src="./axios.js"></script>


<script>
    // const p1 = axios.get('http://ajax-api.itheima.net/api/province')
    // axios.get('http://ajax-api.itheima.net/api/province').then().catch
    // console.log(p1)



    // 1. new 一个 XMLHttpRequest
    // const xhr = new XMLHttpRequest()
    // // 2. 设置请求方式和地址
    // xhr.open('get', 'http://ajax-api.itheima.net/api/province')
    // // 3. 发送
    // xhr.send()
    // // 4. 监听load事件,取到服务器回来的数据
    // xhr.addEventListener('load', () => {
    //     console.log(xhr.response) // JSON字符串
    //     console.log(JSON.parse(xhr.response))
    // })


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

    //         // 写代码 

    //     })

    //     return p
    // }
    // f().then().catch()

    function myAjax() {
        const p = new Promise((resovle, reject) => {
            // 1. new 一个 XMLHttpRequest
            const xhr = new XMLHttpRequest()
            // 2. 设置请求方式和地址
            xhr.open('get', 'http://ajax-api.itheima.net/api/province')
            // 3. 发送
            xhr.send()
            // 4. 监听load事件,取到服务器回来的数据
            xhr.addEventListener('load', () => {
                resovle( JSON.parse(xhr.response) )
                // console.log(xhr.response) // JSON字符串
                // console.log(JSON.parse(xhr.response))
            })
        })

        return p
    }
    
    myAjax()
    .then(res => { console.log('ok', res) })
    .catch(err => { console.log(err) })

    


</script>

11.promise面试题

<script>
function sleep(time){
    // 请写出你的代码
    return new Promise((resolve, reject) => {
        // setTimeout(() => {
        //     resolve()
        // }, time)

        setTimeout(resolve, time)
    })
    // const p = new Promise((resolve, reject) => {
    //     setTimeout(() => {
    //         resolve()
    //     }, time)
    // })
    // return p

}

sleep(2000).then(()=>{
    console.log("后续操作")
})
console.log(2);
</script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值