首页 > 其他分享 >AJAX学习(四)-(axios核心的原理)

AJAX学习(四)-(axios核心的原理)

时间:2023-10-28 21:03:13浏览次数:23  
标签:axios const xhr AJAX resolve Promise new 原理 config

一、Promise

1.定义

Promise对象用于表示一个异步操作的最终完成(或失败)及其结果值

我们用一张图来清晰的看Promise位于哪里AJAX学习(四)-(axios核心的原理)_封装

2.好处

1.逻辑更清晰

2.了解axios函数内部运作机制

3.能解决回调函数地狱问题

3.使用语法及步骤AJAX学习(四)-(axios核心的原理)_html_02

示例代码如下:

<!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>认识Promise</title>
</head>

<body>
  <script>
    /**
     * 目标:使用Promise管理异步任务
    */


    //1创建Promise对象
    const p = new Promise((resolve, reject) => {
      //2执行异步代码
      setTimeout(() => {
        resolve('模拟AJAX请求-成功结果')
      
      }, 2000);
    })

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

</html>

AJAX学习(四)-(axios核心的原理)_ios_03

//1创建Promise对象

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

      //2执行异步代码

      setTimeout(() => {

        //resolve('模拟AJAX请求-成功结果')
		reject(new Error('模拟AJAX请求-失败结果'))
      

      }, 2000);

    })

AJAX学习(四)-(axios核心的原理)_html_04

根据例子不难看出当我们成功的时候,会调用resolve函数,失败的时候会调用reject函数

二、Promise的三种状态

1.作用

了解Promise对象如何关联处理函数,以及代码执行顺序

2.概念

一个Promise对象,必然处于以下几种状态之一

待定(pending):初始状态,既没有被兑现,也没有被拒绝

已兑现(fulfilled):意味着,操作成功完成

已拒绝(rejected):意味着,操作失败

AJAX学习(四)-(axios核心的原理)_封装_05

注意:Promise对象一旦被兑现/拒绝就是已敲定了,状态无法再被改变

<!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>认识Promise状态</title>
</head>

<body>
  <script>
    /**
     * 目标:认识Promise状态
    */
    // 1. 创建Promise对象(pending-待定状态)
    const p = new Promise((resolve, reject) => {
      //Promise对象创建时,这里的代码都会执行了
      // 2. 执行异步代码
      setTimeout(() => {
        //resolve() =>'fulfilled状态-已兑现'=>then()
        // resolve('模拟AJAX请求-成功结果')
        //reject() =>'rejected状态-已拒绝' =>catch()
        reject(new Error('模拟AJAX请求-失败结果'))
      }, 2000)
    })
    console.log(p)

    // 3. 获取结果
    p.then(result => {
      console.log(result)
    }).catch(error => {
      console.log(error)
    })


  </script>
</body>

</html>

我们打印Promise对象看看

AJAX学习(四)-(axios核心的原理)_ios_06

注意:是在异步代码为执行之前查看的,也就是说此时setTimeout函数还并没有执行

我们来看看异步代码执行以后的状态

AJAX学习(四)-(axios核心的原理)_ios_07

此时就成了rejected状态,状态改变,就会调回.catch()去执行reject()

反之成功,会触发.then()去执行resolve()

AJAX学习(四)-(axios核心的原理)_封装_08

总结来说,当Promise对象状态变为fulfilled,就会去.then()就会触发,反之触发.catch()

三、获取省份列表案例

<!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>案例_使用Promise+XHR_获取省份列表</title>
</head>

<body>
  <p class="my-p"></p>
  <script>
    /**
     * 目标:使用Promise管理XHR请求省份列表
     *  1. 创建Promise对象
     *  2. 执行XHR异步代码,获取省份列表
     *  3. 关联成功或失败函数,做后续处理
    */

    //1. 创建Promise对象
    const p = new Promise((resolve, reject) => {
      // 2. 执行XHR异步代码,获取省份列表
      const xhr = new XMLHttpRequest()
      xhr.open('GET', 'https://hmajax.itheima.net/api/province')
      //xhr如何判断响应成功还是失败?
      //2xx开头的都是成功响应状态码
      xhr.addEventListener('loadend', () => {
        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)
      //服务器返回错误提示消息,插入到p标签显示
      document.querySelector('.my-p').innerHTML = error.message
    })

  </script>
</body>

</html>

状态响应码给大家放下面

AJAX学习(四)-(axios核心的原理)_封装_09

四、封装_简易axios

1.获取省份列表

因为axios最核心的两个技术已经学过了AJAX学习(四)-(axios核心的原理)_html_10

所以现在我们可以封装一个简易的axios函数,通过使用我们自己axios函数来实现该功能

话不多说上码:

<!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>封装_简易axios函数_获取省份列表</title>
</head>

<body>
  <p class="my-p"></p>
  <script>
    /**
     * 目标:封装_简易axios函数_获取省份列表
     *  1. 定义myAxios函数,接收配置对象,返回Promise对象
     *  2. 发起XHR请求,默认请求方法为GET
     *  3. 调用成功/失败的处理程序
     *  4. 使用myAxios函数,获取省份列表展示
    */


    //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: 'https://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>

2.获取地区列表

通过上述例子我们发现上述封装的axios函数不支持传递查询参数

AJAX学习(四)-(axios核心的原理)_html_11

所以我们继续改进

<!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>封装_简易axios函数_获取地区列表</title>
</head>

<body>
  <p class="my-p"></p>
  <script>
    /**
     * 目标:封装_简易axios函数_获取地区列表
     *  1. 判断有params选项,携带查询参数
     *  2. 使用URLSearchParams转换,并携带到url上
     *  3. 使用myAxios函数,获取地区列表
    */
    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 querString = paramsObj.toString()
          config.url += `?${querString}`
        }

        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: 'https://hmajax.itheima.net/api/area',
      params: {
        pname: '辽宁省',
        cname: '大连市'
      }

    }).then(result => {
      console.log(result)
      document.querySelector('.my-p').innerHTML = result.list.join('<br>')
    })
  </script>
</body>

</html>

AJAX学习(四)-(axios核心的原理)_封装_12

我们发现相对于第一个例子来说,我们第二个例子里的myAxios函数只多了一段代码

//1. 判断有无params选项,携带查询参数

        if (config.params) {

          //2. 使用URLSearchParams转换,并携带到url上

          const paramsObj = new URLSearchParams(config.params)

          const querString = paramsObj.toString()

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

        }

也就是这段用来判断有无params选项的代码

但是我们发现这样还是不够,如果出现下面这种情况阁下又该怎么办呢?AJAX学习(四)-(axios核心的原理)_ios_13

相信根据例2的问题以后大家心里都有思路了

3.注册用户功能

<!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>封装_简易axios函数_注册用户</title>
</head>

<body>
  <button class="reg-btn">注册用户</button>
  <script>
    /**
     * 目标:封装_简易axios函数_注册用户
     *  1. 判断有data选项,携带请求体
     *  2. 转换数据类型,在send中发送
     *  3. 使用myAxios函数,完成注册用户
    */
    function myAxios(config) {
      return new Promise((resolve, reject) => {
        const xhr = new XMLHttpRequest()

        if (config.params) {
          const paramsObj = new URLSearchParams(config.params)
          const queryString = paramsObj.toString()
          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))
          }
        })
        //1. 判断有data选项,携带请求体
        if (config.data) {
          // 2. 转换数据类型,在send中发送
          const jsonStr = JSON.stringify(config.data)
          xhr.setRequestHeader('Content-Type', 'application/json')
          xhr.send(jsonStr)
        } else {
        //如果没有请求体数据,正常的发起请求
          xhr.send()
        }

      })
    }


    const btn = document.querySelector('.reg-btn')
    btn.addEventListener('click', () => {
      // 3. 使用myAxios函数,完成注册用户
      myAxios({
        url: 'https://hmajax.itheima.net/api/register',
        method: 'POST',
        data: {
          username: 'itheima999',
          password: '666666'
        }
      }).then(result => {
        console.log(result)
      }).catch(error => {
        console.dir(error)
      })
    })
  </script>
</body>

</html>

由于我已经注册过该账户了,所以会提示账号被占用了

AJAX学习(四)-(axios核心的原理)_封装_14

那么这样我们自己封装的axios函数是不是就完成了呀,我们这样就更能理解axios函数的原理了


标签:axios,const,xhr,AJAX,resolve,Promise,new,原理,config
From: https://blog.51cto.com/u_15858858/8072936

相关文章

  • Proxy Facade 设计模式运行时的工作原理介绍
    ProxyFacade设计模式是一个强大的工具,它可以帮助我们创建一个简单的代理外观类,以便根据方法和属性的配置来访问系统的各种功能。在这篇文章中,我们将深入探讨ProxyFacade模式的运行时工作原理,并提供一些实际示例来帮助您更好地理解。什么是ProxyFacade设计模式?ProxyFaca......
  • 1、Keepalived原理使用
    keepalived是一个类似于layer3,4&5交换机制的软件,也就是我们平时说的第3层、第4层和第5层交换。Keepalived的作用是检测web服务器的状态,如果有一台web服务器死机,或工作出现故障,Keepalived将检测到,并将有故障的web服务器从系统中剔除,当web服务器工作正常后Keepalived自动将web......
  • Java Hotspot G1 GC 原理
    目录原理概念初始堆占用情况标记RememberSet原理CardTableCollectSet停顿预测模型G1的垃圾回收过程对象分配线程本地分配缓冲区Eden区中分配Humongous区分配堆内存结构传统的GC收集器G1收集器G1垃圾收集周期YoungGCYoungGC总结MixedGC全局并发标记初始标记根区域扫描......
  • 如果防止axios发送重复请求
    封装axios请求文件添加函数importaxiosfrom'axios'importqsfrom'qs'//用于存储pending的请求的数组(处理多条相同请求)constpendingRequest=newMap()//生成request的唯一keyconstgenerateRequestKey=(config={})=>{//通过url,method,params,data生成唯一k......
  • vue中使用axios请求post接口为什么先发起OPTIONS请求再发起post请求?
    在使用Axios进行跨域POST请求时,浏览器会先发起一个OPTIONS请求,这是因为浏览器执行了跨域请求时的预检请求(PreflightRequest)。这是一个安全性措施,旨在确保跨域请求不会导致安全风险。1、跨域请求的安全性:当前端应用和后端API位于不同的域或端口时,浏览器会执行同源策略,以防止跨站点......
  • 抓住重点的思考能力如何训练,批判性思维和金字塔原理
    读教科书感觉有点晦涩,阅读英文文章有时候不能抓住重点,感觉需要训练自己这方面的能力,多看看纸质书。其实我觉得我和别人交流的时候,有那种答非所问的倾向,说明我不善于抓住重点。当然一方面是因为我可能要忽略那些我不想回答的东西,另一方面就是思考能力的缺乏了为什么有人思考问题......
  • 微机原理与接口技术中断实验
    ;*******************************;;*中断实验IRQ3*;;*******************************;includeio.inc.modelsmall;定义程序的存储模式.stack;定义堆栈段(默认是1KB空间).datamsgbyte'TPCAinterruptNo.3!',0dh,0ah,0c......
  • form表单和ajax提交的重复
    form表单和ajax提交的重复form表单中input的submit类型和button按钮都会触发两次(有ajax的情况),当我们把input的type改成button类型就不会朝后端再发送POST请求了<formaction=""method="post">用户名:<inputtype="text"name="username"id="id_user">......
  • 微机原理与接口技术-第八章常用接口技术
    目录定时控制接口8253/8254定时器定时器的应用并行接口并行接口电路8255内部引脚工作方式工作方式0:基本输入输出方式工作方式1:选通输入输出方式编程并行接口的应用用8255方式0与打印机接口数码管及其接口数码管的工作原理单个数码管的显示多个数码管的显示异步串行通讯接口模拟接......
  • 手撕Vuex-Vuex实现原理分析
    本章节主要围绕着手撕Vuex,那么在手撕之前,先来回顾一下Vuex的基本使用。创建一个Vuex项目,我这里采用vue-cli创建一个项目,然后安装Vuex。vuecreatevuex-demo选择Manuallyselectfeatures。这里只需要,Babel与Vuex。选择2.X版本的Vue:创建package.json:是......