AJAX-day03-AJAX进阶

简介: AJAX-day03-AJAX进阶

(创作不易,感谢有你,你的支持,就是我前行的最大动力,如果看完对你有帮助,请留下您的足迹)

目录

同步代码和异步代码

回调函数地狱  

Promise - 链式调用  

Promise 链式应用

async函数和await

async函数和await_捕获错误

事件循环-EventLoop  

认识 - 事件循环(EventLoop)

事件循环 - 执行过程

总结

宏任务与微任务

宏任务与微任务 - 执行顺序


同步代码和异步代码

同步代码:

异步代码:

同步代码:逐行执行,需原地等待结果后,才继续向下执行

异步代码:调用后 耗时,不阻塞代码继续执行(不必原地等待),在将来完成后触发一个回调函数

回调函数地狱  

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

概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱

缺点:可读性差,异常无法捕获,耦合性严重,牵一发动全身

<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 => {
      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 => {
          console.log(result)
          const areaName = result.data.list[0]
          document.querySelector('.area').innerHTML = areaName
        })
      })
    }).catch(error => {
      console.dir(error)
    })
  </script>
</body>

Promise - 链式调用  

概念:依靠 then() 方法会返回一个 新生成的 Promise 对象 特性,继续串联下一环任务,直到结束

细节:then() 回调函数中的 返回值 ,会影响新生成的 Promise 对象 最终状态和结果

好处:通过链式调用,解决回调函数嵌套问题

<body>
  <script>
    /**
     * 目标:掌握Promise的链式调用
     * 需求:把省市的嵌套结构,改成链式调用的线性结构
    */
    // 1. 创建Promise对象-模拟请求省份名字
    const p = new Promise((resolve, reject) => {
      setTimeout(() => {
        resolve('北京市')
      }, 2000)
    })
    // 2. 获取省份名字
    const p2 = p.then(result => {
      console.log(result)
      // 3. 创建Promise对象-模拟请求城市名字
      // return Promise对象最终状态和结果,影响到新的Promise对象
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          resolve(result + '--- 北京')
        }, 2000)
      })
    })
    // 4. 获取城市名字
    p2.then(result => {
      console.log(result)
    })
    // then()原地的结果是一个新的Promise对象
    console.log(p2 === p)
  </script>
</body>

Promise 链式应用

目标:使用 Promise 链式调用,解决回调函数地狱问题

做法:每个 Promise 对象中管理一个异步任务,用 then 返回 Promise 对象,串联起来

<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>
    /**
     * 目标:把回调函数嵌套代码,改成Promise链式调用结构
     * 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中
    */
    let pname = ''
    // 1. 得到-获取省份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 => {
      console.log(result)
      const areaName = result.data.list[0]
      document.querySelector('.area').innerHTML = areaName
    })
  </script>
</body>

async函数和await

定义:

概念:在 async 函数内,使用 await 关键字取代 then 函数,等待获取 Promise 对象成功状态的结果值

<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和await语法,解决回调函数地狱
     * 概念:在async函数内,使用await关键字,获取Promise对象"成功状态"结果值
     * 注意:await必须用在async修饰的函数内(await会阻止"异步函数内"代码继续执行,原地等待结果)
    */
    // 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>

async函数和await_捕获错误

使用:

语法:

事件循环-EventLoop  

认识 - 事件循环(EventLoop)

概念:

原因:JavaScript 单线程(某一刻只能执行一行代码),为了让耗时代码不阻塞其他代码运行,设计了事件循环模型

事件循环 - 执行过程

定义:执行代码和收集异步任务的模型,在调用栈空闲,反复调用任务队列里回调函数的执行机制,就叫事件循环

总结

1. 什么是事件循环?

        执行代码 和收集异步任务,在调用栈空闲时,反复调用任务队列里回调函数执行机制

2. 为什么有事件循环?

       JavaScript 是单线程的,为了 不阻塞 JS 引擎 ,设计执行代码的模型

3. JavaScript 内代码如何执行?

       执行同步代码,遇到 异步代码 交给 宿主 浏览器环境执行

       异步有了结果后,把回调函数放入 任务队列排队

       当调用栈 空闲 后,反复调用任务队列里的回调函数

宏任务与微任务

ES6 之后引入了 Promise 对象, 让 JS 引擎也可以发起异步任务

异步任务分为:

        宏任务 :由 浏览器 环境执行的异步代码

        微任务 :由 JS 引擎 环境执行的异步代码

Promise 本身是同步的,而then和catch回调函数是异步的

宏任务与微任务 - 执行顺序

相关文章
|
Java 数据库连接 API
SpringMVC中使用JSR303进行数据校验实践详解
SpringMVC中使用JSR303进行数据校验实践详解
405 7
|
存储 SQL 分布式数据库
OceanBase 入门:分布式数据库的基础概念
【8月更文第31天】在当今的大数据时代,随着业务规模的不断扩大,传统的单机数据库已经难以满足高并发、大数据量的应用需求。分布式数据库应运而生,成为解决这一问题的有效方案之一。本文将介绍一款由阿里巴巴集团自主研发的分布式数据库——OceanBase,并通过一些基础概念和实际代码示例来帮助读者理解其工作原理。
1073 0
|
存储 监控 安全
【实战经验】记录项目开发常见的8个难题
风沙席地起,战马踏风归!
577 115
|
11月前
|
JavaScript
vue-router学习三:封装组件,封装TabBar组件。
这篇文章是关于如何使用Vue.js和vue-router封装一个自定义的TabBar组件的教程。
119 0
|
11月前
|
缓存 监控 安全
电商行业中 API 接口的常见问题和解决方法?
电商行业中 API 接口面临的常见问题包括安全性问题、性能问题、兼容性问题、可靠性问题和可维护性问题。针对这些问题,可以采取相应的解决方法,如采用加密技术、优化数据库查询、制定统一的接口规范、进行容错处理、采用良好的代码结构等。
382 0
|
安全 API 数据安全/隐私保护
​6个值得测试的发送邮件接口API
在数字营销和企业通信中,发送邮件接口API如SendGrid、Mailgun、Amazon SES、AOKSend、Postmark和Sendinblue是关键工具。这些API自动化邮件发送,提高效率,确保及时送达。各具特色,如SendGrid和Mailgun适合大规模发送,AOKSend易于集成,Postmark专于事务邮件,而Sendinblue提供综合营销解决方案。根据企业需求,如邮件量、成本、功能和集成简易度,可选择最适合的API服务。
|
监控 Oracle 数据可视化
深度解析JVM性能监控工具:推荐与详细用法
深度解析JVM性能监控工具:推荐与详细用法
1518 0
|
前端开发 JavaScript BI
JavaScript的过滤大师:深度解析Filter用法
JavaScript的过滤大师:深度解析Filter用法
628 0
|
SQL 存储 算法
SpringBoot整合ShardingSphere实现分表分库&读写分离&读写分离+数据库分表
SpringBoot整合ShardingSphere实现分表分库&读写分离&读写分离+数据库分表
2673 0
SpringBoot整合ShardingSphere实现分表分库&读写分离&读写分离+数据库分表
|
算法 C语言
KMP算法详解(理论+C语言代码实现)(上)
KMP算法详解(理论+C语言代码实现)
293 0