首页 > 其他分享 >AJAX-解决回调函数地狱问题

AJAX-解决回调函数地狱问题

时间:2023-11-01 18:32:03浏览次数:35  
标签:地狱 const 函数 await AJAX Promise result pname

一、同步代码和异步代码

1.同步代码

浏览器是按照我们书写代码的顺序一行一行地执行程序的。浏览器会等待代码的解析和工作,在上一行完成之后才会执行下一行。这也使得它成为一个同步程序

总结来说:逐行执行,需原地等待结果后,才继续向下执行

2.异步代码

异步编程技术使你的程序可以在一个可能长期运行的任务的同时继续对其他事件做出反应而不必等待任务完成。与此同时,你的程序也将在任务完成后显示结果。

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

3.JS中有哪些异步代码

setTimeout/setinterval

事件

AJAX

4.异步代码如何接收结果

依靠回调函数来接收

5.示例

AJAX-解决回调函数地狱问题_ios

AJAX-解决回调函数地狱问题_.net_02

AJAX-解决回调函数地狱问题_.net_03

1作为同步代码,立即执行,往下是3,是一个异步代码,先放一边,4也是一个异步代码,也放一边,2是一个同步代码,立即执行,然后等两秒一过,3开始执行,4是点击才执行

二、回调函数地狱

1.回调函数地狱代码演示

<!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>回调地狱</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>
    /**
     * 目标:演示回调函数地狱
     * 需求:获取默认第一个省,第一个市,第一个地区并展示在下拉菜单中
     * 概念:在回调函数中嵌套回调函数,一直嵌套下去就形成了回调函数地狱
     * 缺点:可读性差,异常无法获取,耦合性严重,牵一发动全身
    */

    axios({ url: 'https://hmajax.itheima.net/api/province' }).then(result => {
      console.log(result)
      const pname = result.data.list[0]
      document.querySelector('.province').innerHTML = pname

      //2获取默认第一个城市的名字
      axios({ url: 'https://hmajax.itheima.net/api/city', params: { pname } }).then(result => {
        console.log(result)
        const cname = result.data.list[0]
        document.querySelector('.city').innerHTML = cname

        //3获取默认第一个地区的名字
        axios({ url: 'https://hmajax.itheima.net/api/area', params: { pname, cname } }).then(result => {
          const areaName = result.data.list[0]
          document.querySelector('.area').innerHTML = areaName
        })
      })
    })

  </script>
</body>

</html>

AJAX-解决回调函数地狱问题_AJAX_04

2.概念及缺点

通过上面例子我们不难发现,回调函数中嵌套着回调函数一直嵌套着下去就形成了回调函数地狱

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

三、解决回调函数地狱问题

1.Promise-链式调用

(1)概念

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

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

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

AJAX-解决回调函数地狱问题_.net_05

(2)模拟代码

<!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) => {
      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);
      })
    })

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

</html>

AJAX-解决回调函数地狱问题_回调函数_06

(3)实际案列代码

AJAX-解决回调函数地狱问题_AJAX_07

<!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>
  <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 得到省份的Promsi对象
    axios({ url: 'https://hmajax.itheima.net/api/province' }).then(result => {
      pname = result.data.list[0]
      document.querySelector('.province').innerHTML = pname

      //2 获取城市
      return axios({ url: 'https://hmajax.itheima.net/api/city', params: { pname } })
    }).then(result => {
      const cname = result.data.list[0]
      document.querySelector('.city').innerHTML = cname
      //3.获取地区
      return axios({ url: 'https://hmajax.itheima.net/api/area', params: { pname, cname } })
    }).then(result => {
      const areaName = result.data.list[0]
      document.querySelector('.area').innerHTML = areaName
    })
  </script>
</body>

</html>

AJAX-解决回调函数地狱问题_ios_08

2.async函数和await

(1) 定义

async函数是使用async关键字声明的函数。async函数是AsyncFunction构造函数的实例,并且其中运行使用await关键字。async和await关键字让我们可以用一种更简洁的方式写出基于Promise的异步行为而无需刻意地链式调用promise.

(2)概念

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

(3)代码示例

AJAX-解决回调函数地狱问题_回调函数_09

AJAX-解决回调函数地狱问题_AJAX_10

<!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>async函数和await_解决回调函数地狱</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>
    /** 
     * 目标:掌握async和await语法,解决回调函数地狱
     * 概念:在async函数内,使用await关键字,获取Promise对象"成功状态"结果值
     * 注意:await必须用在async修饰的函数内(await会阻止"异步函数内"代码继续执行,原地等待结果)
    */
    //1.定义一个async修饰函数
    async function getData() {
    //2.await等待Promise对象成功的结果
      const pObj = await axios({ url: 'https://hmajax.itheima.net/api/province' })
      const pname = pObj.data.list[0]
      const cObj = await axios({ url: 'https://hmajax.itheima.net/api/city', params: { pname } })
      const cname = cObj.data.list[0]
      const aObj = await axios({ url: 'https://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>

AJAX-解决回调函数地狱问题_回调函数_11

(4)async函数和await捕获错误

使用及语法:

AJAX-解决回调函数地狱问题_AJAX_12

示例如下:

<!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>async函数和await_错误捕获</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>
    /**
     * 目标:async和await_错误捕获
    */

    async function getData() {
		//1.try包裹可能产生错误的代码
      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]
        //我们将获取地区的资源路径写错多写一个1
        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) {
      //2.接着调用catch块,接收错误信息
      //如果try里某行代码报错后,try中剩余代码不会执行了
        console.dir(error)
      }

    }

    getData()
  </script>
</body>

</html>

AJAX-解决回调函数地狱问题_AJAX_13


标签:地狱,const,函数,await,AJAX,Promise,result,pname
From: https://blog.51cto.com/u_15858858/8131216

相关文章

  • 递归函数实现省市区多级联动搜索帮助
    1、需求背景当程序中有互为层级的字段,需要使用搜索帮助时,可以通过多次调用搜索帮助来实现。比如在程序中需要填写省市区三级地址2、实现方式2.1、平铺直叙程序的搜索帮助,通常使用F4IF_INT_TABLE_VALUE_REQUEST来实现。多级的搜索帮助,可以简单的通过多次调用F4函数来实现。点......
  • 【keng】 Vue2 多次传参进入同一页面 页面不走生命周期函数
    比如一个搜索跳转功能 搜索123进入页面加载数据再次搜索456 还是进入这个页面这个页面就不会走生命周期了 解决方案在App.vue上为router-view增加一个key 这个key就是随便写一个随机数就可以不要重复eg:  ......
  • 【javascript】关于匿名函数
    什么是匿名函数?没有名字的函数,叫匿名函数,匿名函数主要有以下几种常用的场景:回调函数,直接执行函数,箭头函数什么是回调函数?回调函数是一段可执行的代码段,它作为一个参数传递给其他的代码,其作用是在需要的时候方便调用这段(回调函数)代码。(作为参数传递到另外一个函数中,这个作为参数......
  • 数值分析第三课——函数逼近
    就是研究函数和曲线可以近似为另一个函数或数据集,那么怎么来近似尼?逼近算法。两者之间的误差尼?逼近误差。范数、内积、正交函数族、最佳平方逼近是重点一、用python做数学计算importnumpyasnpfromscipy.interpolateimportCubicSplineimportmatplotlib.pyplotaspltx=......
  • 前端歌谣-第贰拾壹课-函数基础
    前言我是歌谣最好的种树是十年前其次是现在今天继续给大家带来的是函数基础环境配置npminit-yyarnaddvite-D修改page.json配置端口{"name":"demo1","version":"1.0.0","description":"","main":"index.js",&q......
  • 前端歌谣-第贰拾贰课-函数参数默认值
    前言我是歌谣最好的种树是十年前其次是现在今天继续给大家带来的是this指向的讲解环境配置npminit-yyarnaddvite-D修改page.json配置端口{"name":"demo1","version":"1.0.0","description":"","main":"index.js",......
  • Opencv中goodFeaturesToTrack函数(Harris角点、Shi-Tomasi角点检测)算子速度的进一步
    搜索到某个效果很好的视频去燥的算法,感觉效果比较牛逼,就是速度比较慢,如果能做到实时,那还是很有实用价值的。于是盲目的选择了这个课题,遇到的第一个函数就是角点检测,大概六七年用过C#实现过Harris角点以及SUSAN角点。因此相关的理论还是有所了解的,不过那个时候重点在于实现,对于......
  • 当我们在谈论构造函数注入的时候我们在谈论什么
    依赖注入当涉及依赖注入(DependencyInjection,DI)时,首先推荐使用构造函数注入,因为构造函数注入有很多技术优点,而且还与面向对象的设计原则密切相关。在业界,构造函数注入作为依赖注入的一种最佳实践得到了广泛的认可,在SpringFramework的作者之一RodJohnson的观点中也得有体现。下......
  • SAP CDS view 里的 COALESCE 函数
    在SAPABAPCDS(CoreDataServices)View中,COALESCE函数是用于处理NULL值的一种功能。COALESCE函数接受多个参数,并返回第一个非NULL值参数。这意味着如果第一个参数不为NULL,则返回第一个参数的值;如果第一个参数为NULL,则返回第二个参数的值;以此类推,直到找到第一个非NUL......
  • 实验3_c语言函数应用编程
    task1#include<stdio.h>#include<stdlib.h>#include<time.h>#include<windows.h>#defineN80voidprint_text(intline,intcol,chartext[]);voidprint_spaces(intn);voidprint_blank_lines(intn);intmain(){intline,col......