day02-Promise
Promise
1.Promise基本介绍
Promise是异步编程的一种解决方案,可以解决传统Ajax回调函数嵌套问题。
- 传统的Ajax异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的Callback Hell
 - 为了解决上述的问题,Promise对象应运而生,在EMCAScript 2015当中已经成为标准,Promise也是ES6的新特性
 - Promise是异步编程的一种解决方案
 - 从语法上说,Promise是一个对象,从它可以获取异步操作的消息
 
2.Promise应用实例
2.1需求分析/图解
需求:演示promise异步请求使用
执行效果:


2.2代码实现
使用json文件模拟数据库表数据

monster.json
{
  "id": 1,
  "name": "黑山老妖"
}
monster_detail_1.json
{
  "id": 1,
  "address": "黑山洞",
  "skill": "翻江倒海",
  "age": 500,
  "gfid": 2
}
monster_gf_2.json
{
  "name": "狐狸精",
  "age": 100
}
2.2.1jquery-ajax实现多次ajax请求
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax多次请求</title>
    <!--引入jquery-->
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //jquery发出ajax的方式
        $.ajax({
            url: "data/monster.json",
            success(resultData) {//第一次ajax成功的回调函数
                console.log("第一次ajax请求 monster 基本信息=", resultData);
                //发出第二次ajax请求
                $.ajax({
                    //第二次ajax请求的url根据第一次的结果来改变
                    url: `data/monster_detail_${resultData.id}.json`,
                    success(resultData) {//第二次ajax成功的回调函数
                        console.log("第二次ajax请求 monster 详细信息=", resultData);
                    },
                    error(err) {
                        console.log("第二次ajax请求出现异常=", err);
                    }
                })
            },
            error(err) {
                console.log("第一次ajax请求出现异常=", err);
            }
        })
    </script>
</head>
<body>
</body>
</html>

使用jquery-ajax的方式容易出现回调函数嵌套(Callback Hell),如果发出的是多次ajax请求,那么嵌套的层数将会变得非常多,代码不易读。这种写法冗余度高,代码可维护性低。
2.2.2promise对象实现多次ajax请求

首先创建一个Promise对象,在该对象内传入一个箭头函数,箭头函数内进行ajax请求。Promise对象的箭头函数传入了两个方法作为参数(命名随意),这里的resolve方法是ajax请求成功后调用的函数,reject方法是ajax请求失败后调用的函数。不同于jquery的回调嵌套,在ajax请求成功的success方法中会调用resolve(),并且把第一次ajax请求获得的数据传入该方法。
resolve方法会跳到Promise对象的then()方法,then方法中可以继续使用$.ajax()去进行第二次ajax请求。在then方法中,又创建了一个Promise对象,该对象和之前的Promise对象中的业务逻辑相似,不同的是可以通过上一次的resolve方法,拿到第一次ajax请求返回的数据,然后根据数据进行第二次的ajax请求.......在第二次的ajax请求中,又可以获取第二次ajax请求返回的数据,然后调用这次Promise对象的resolve(),将新的数据传给这次Promise对象的then()方法.....
即,第二次ajax请求的resolve方法又会跳到Promise对象的then()方法........以此类推。
整个过程形成了一个链式的调用。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>使用promise完成多次ajax请求</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //先请求到monster.json
        //1.创建Promise对象
        //2.构造函数需要传入一个箭头函数
        //3.(resolve, reject)参数列表,resolve:如果请求成功,调用resolve函数
        //                           reject:如果请求失败,调用reject函数
        //4.箭头函数体内仍然是通过jquery发出ajax
        let promise = new Promise((resolve, reject) => {
            //发出ajax请求
            $.ajax({
                url: "data/monster.json",
                success(resultData) {//第一次ajax请求成功的回调函数
                    console.log("Promise发出的第一次ajax请求,返回的monster基本信息=", resultData);
                    resolve(resultData);
                },
                error(err) {
                    //console.log("Promise第一次异步请求出现异常=", err);
                    reject(err);
                }
            })
        });
        //这里我们可以继续编写第一次请求成功之后的业务
        //仍然使用箭头函数
        promise.then((resultData) => {
            //这里可以继续发出请求
            return new Promise((resolve, reject) => {
                $.ajax({
                    url: `data/monster_detail_${resultData.id}.json`,
                    success(resultData) {//第二次ajax请求成功的回调函数
                        console.log("Promise发出的第二次ajax请求,返回的monster详细信息=", resultData);
                        //可以继续进行下一次的请求
                        resolve(resultData);
                    },
                    error(err) {
                        //console.log("Promise第二次异步请求出现异常=", err);
                        reject(err);
                    }
                })
            })
        }).then((resultData) => {
            console.log("promise.then().then(),resultDate", resultData);
            //这里可以继续发出第三次ajax请求....
            return new Promise(((resolve, reject) => {
                $.ajax({
                    url: `data/monster_gf_${resultData.gfid}.json`,
                    success(resultData) {//第二次ajax请求成功的回调函数
                        console.log("Promise发出的第三次ajax请求,返回的monster gf信息=", resultData);
                        //可以继续进行下一次的请求
                        //resolve(resultDate);
                    },
                    error(err) {
                        //console.log("Promise第三次次异步请求出现异常=", err);
                        reject(err);
                    }
                })
            }))
        }).catch((err) => {//这里可以对多次ajax请求的异常进行处理
            console.log("promise异步请求异常=", err);
        })
    </script>
</head>
<body>
</body>
</html>

2.2.3promise代码重排
虽然在2.2.2中使用promise实现了多次ajax请求,解决了jquery-ajax的嵌套回调问题,但是代码仍然显得臃肿。创建Promise对象和进行ajax请求的代码是重复的,因此可以进行封装,代码重排,增强可读性。
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>promise代码重排</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        /**
         * 这里我们将重复的代码封装,编写为get方法
         * @param url ajax请求的资源
         * @param data ajax请求携带的数据
         * @returns {Promise<unknown>}
         */
        function get(url, data) {
            return new Promise(((resolve, reject) => {
                $.ajax({
                    url: url,
                    data: data,
                    success(resultData) {
                        resolve(resultData);
                    },
                    error(err) {
                        reject(err);
                    }
                })
            }))
        }
        //需求:完成
        //1.先获取monster.json
        //2.再获取monster_detail_1.json
        //3.再获取monster_gf_2.json
        get("data/monster.json").then((resultData) => {
            //第一次ajax请求成功后的处理代码
            console.log("第1次ajax请求返回的数据=", resultData);
            return get(`data/monster_detail_${resultData.id}.json`);
        }).then((resultData) => {
            //第二次ajax请求成功后的处理代码
            console.log("第2次ajax请求返回的数据=", resultData);
            return get(`data/monster_gf_${resultData.gfid}.json`);
        }).then((resultData) => {
            //第三次ajax请求成功后的处理代码
            console.log("第3次ajax请求返回的数据=", resultData);
            //如果还有就继续...
        }).catch(err => {
            console.log("请求出现异常=", err)
        })
    </script>
</head>
<body>
</body>
</html>

3.练习
分别使用Jquery-Ajax和Promise代码重排,完成如下功能,发出3次ajax请求,获取对应的数据,注意体会Promise发出多次Ajax请求的方便之处。

student_100.json
{
  "id": 100,
  "name": "jack",
  "class_id": 10
}
class_10.json
{
  "id": 10,
  "name": "java工程师班级",
  "student_num": 30,
  "school_id": 9
}
school_9.json
{
  "id": 9,
  "name": "清华大学",
  "address": "北京"
}
3.1jquery-ajax方式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax</title>
    <script type="text/javascript" src="../script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //第一次ajax请求
        $.ajax({
            url: "data/student_100.json",
            success(resultData) {
                console.log("第一次ajax请求=", resultData);
                //第二次ajax请求
                $.ajax({
                    url: `data/class_${resultData.class_id}.json`,
                    success(resultData) {
                        console.log("第二次ajax请求=", resultData);
                        //第三次ajax请求
                        $.ajax({
                            url: `data/school_${resultData.school_id}.json`,
                            success(resultData) {
                                console.log("第三次ajax请求=", resultData);
                            },
                            error(err) {
                                console.log("第三次ajax请求出现异常=", err);
                            }
                        })
                    },
                    error(err) {
                        console.log("第二次ajax请求出现异常=", err);
                    }
                })
            },
            error(err) {
                console.log("第一次ajax请求出现异常=", err);
            }
        })
    </script>
</head>
<body>
</body>
</html>

3.2Promise代码重排
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>promise代码重排</title>
    <script type="text/javascript" src="../script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //get方法也可以封装到js工具类,重复使用
        function get(url, data) {
            return new Promise(((resolve, reject) => {
                $.ajax({
                    url: url,
                    data: data,
                    success(resultData) {
                        resolve(resultData);
                    },
                    error(err) {
                        reject(err);
                    }
                })
            }))
        }
        //业务
        get("data/student_100.json").then(resultData => {
            console.log("第1次返回的数据=", resultData);
            return get(`data/class_${resultData.class_id}.json`);
        }).then(resultData => {
            console.log("第2次返回的数据=", resultData);
            return get(`data/school_${resultData.school_id}.json`);
        }).then(resultData => {
            console.log("第3次返回的数据=", resultData);
            //如有需求可以继续请求...
        }).catch(err => {
            console.log("promise异步请求异常=", err)
        })
    </script>
</head>
<body>
</body>
</html>

day02-Promise的更多相关文章
- Javascript - Promise学习笔记
		
最近工作轻松了点,想起了以前总是看到的一个单词promise,于是耐心下来学习了一下. 一:Promise是什么?为什么会有这个东西? 首先说明,Promise是为了解决javascript异步编 ...
 - 路由的Resolve机制(需要了解promise)
		
angular的resovle机制,实际上是应用了promise,在进入特定的路由之前给我们一个做预处理的机会 1.在进入这个路由之前先懒加载对应的 .js $stateProvider .state ...
 - angular2系列教程(七)Injectable、Promise、Interface、使用服务
		
今天我们要讲的ng2的service这个概念,和ng1一样,service通常用于发送http请求,但其实你可以在里面封装任何你想封装的方法,有时候控制器之间的通讯也是依靠service来完成的,让我 ...
 - 闲话Promise机制
		
Promise的诞生与Javascript中异步编程息息相关,js中异步编程主要指的是setTimout/setInterval.DOM事件机制.ajax,通过传入回调函数实现控制反转.异步编程为js ...
 - 深入理解jQuery、Angular、node中的Promise
		
最初遇到Promise是在jQuery中,在jQuery1.5版本中引入了Deferred Object,这个异步队列模块用于实现异步任务和回调函数的解耦.为ajax模块.队列模块.ready事件提供 ...
 - Promise的前世今生和妙用技巧
		
浏览器事件模型和回调机制 JavaScript作为单线程运行于浏览器之中,这是每本JavaScript教科书中都会被提到的.同时出于对UI线程操作的安全性考虑,JavaScript和UI线程也处于同一 ...
 - JavaScript进阶之路——认识和使用Promise,重构你的Js代码
		
一转眼,这2015年上半年就过去了,差不多一个月没有写博客了,"罪过罪过"啊~~.进入了七月份,也就意味着我们上半年苦逼的单身生活结束了,从此刻起,我们要打起十二分的精神,开始下半 ...
 - 细说Promise
		
一.前言 JavaScript是单线程的,固,一次只能执行一个任务,当有一个任务耗时很长时,后面的任务就必须等待.那么,有什么办法,可以解决这类问题呢?(抛开WebWorker不谈),那就是让代码异步 ...
 - 浅谈Angular的 $q, defer, promise
		
浅谈Angular的 $q, defer, promise 时间 2016-01-13 00:28:00 博客园-原创精华区 原文 http://www.cnblogs.com/big-snow/ ...
 - angular学习笔记(二十八-附2)-$http,$resource中的promise对象
		
下面这种promise的用法,我从第一篇$http笔记到$resource笔记中,一直都有用到: HttpREST.factory('cardResource',function($resource) ...
 
随机推荐
- C语言常见的八大排序(详解)
			
冒泡排序 优点:写起来简单 缺点:运算量过大每两个之间就要比较一次 冒泡排序在一组需要排序的数组中,对两两数据顺序与要求顺序相反时,交换数据,使大的数据往后移,每趟排序将最大的数放在最后的位置上 如下 ...
 - python基础之数据类型总结
			
一.列表 1.作用:列表主要用于存储多个数据. 2.空列表表示:li=[]或者li=list() 3.列表的索引和切片:同字符串的索引和切片,索引超出范围报错,切片超出范围不报错. list3 = [ ...
 - 一篇文章带你了解服务器操作系统——Linux简单入门
			
一篇文章带你了解服务器操作系统--Linux简单入门 Linux作为服务器的常用操作系统,身为工作人员自然是要有所了解的 在本篇中我们会简单介绍Linux的特点,安装,相关指令使用以及内部程序的安装等 ...
 - 狂神说mysql笔记
			
1.mysql 基本操作 Windows-->Mysql5.7打开 输入用户名和密码 查看数据库 :show databases:查询所有数据库,记住一定要加分号结尾 这里必须全部为 英文空格 ...
 - LAPM概述及配置
			
一.LAMP概述 1.1LAMP的概念 LAMP架构是目前成熟的企业网站应用模式之一,指的是协同工作的一整套系统和相关软件,能够提供动态web站点服务及其应用开发环境 LAMP是一个缩写词,具体包括L ...
 - 聊聊kafka
			
两个月因为忙于工作毫无输出了,最近想给团队小伙伴分享下kafka的相关知识,于是就想着利用博客来做个提前的准备工作了:接下来会对kafka做一个简单的介绍,包括利用akf原则来解析单机下kafk的各个 ...
 - Azure DevOps Server 设置项目管理用户,用户组
			
一,引言 Azure DevOps Server 搭建完成后,关于如何进行项目管理,项目成员管理等,我们接着上一篇文章,继续讲解 Azure DevOps Server 的用户,用户组.首先,我们需要 ...
 - 聊聊FASTER和进程内混合缓存
			
最近有一个朋友问我这样一个问题: 我的业务依赖一些数据,因为数据库访问慢,我把它放在Redis里面,不过还是太慢了,有什么其它的方案吗? 其实这个问题比较简单的是吧?Redis其实属于网络存储,我对照 ...
 - ANSYS安装教程
			
ANSYS 16.0 WIN10 64位安装步骤:1.使用"百度网盘客户端"下载ANSYS 16.0软件安装包到电脑磁盘里全英文名称文件夹内,安装前先断开网络,然后找到ANSYS. ...
 - solidedge型材库/.sldlfp格式转.par
			
一.打开solidworks型材库:D:\Program Files\SOLIDWORKS Corp\SOLIDWORKS\lang\chinese-simplified\weldment profi ...