目录
Promise
Promise 基本介绍
Promise 应用实例
代码实现
monster.json
monster_detail_1.json
先使用 ajax 传统方式完成, 问题分析(出现回调函数嵌套)
使用 promise 方式
示意图:
使用 promise 代码优化/重排 方式完成
get.js方法
注意事项和使用细节
综合代码
student.json
class_12.json
school_9.json
原始ajax请求
promise代码重排完成多次ajax请求
Promise
Promise 基本介绍
1. 传统的 Ajax 异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的 Callback Hell
2. 为了解决上述的问题,Promise 对象应运而生,在 EMCAScript 2015 当中已经成为标准
3. Promise 是异步编程的一种解决方案。
4. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
5. Promise 也是 ES6 的新特性,因为比较重要,老师单独拉出来讲
一句话: Promise 是异步编程的一种解决方案, 可以解决传统 Ajax 回调函数嵌套问题
Promise 应用实例
需求: 演示 promise 异步请求使用(如图)
代码实现
monster.json
{
"id": 1,
"name": "黑山老妖"
}
monster_detail_1.json
{
"address": "阴曹地府-黑山",
"skill": "翻江倒海功",
"age": 800
}
先使用 ajax 传统方式完成, 问题分析(出现回调函数嵌套)
ajax.html
<!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) {//如果请求成功了,回调处理函数success
console.log("第1次ajax请求 monster基本信息=", resultData);
//发出第二次ajax请求
$.ajax({
url: `data/monster_detail_${resultData.id}.json`,
//下面是es6对象的方法简写形式
success(resultData) {
console.log("第2次ajax请求 monster详细信息=", resultData);
//$.ajax => callback hell
//$.ajax
//$.ajax
},
error(err) { //出错的回调函数
console.log("出现异常=", err);
}
})
},
error(err) {
console.log("出现异常=", err);
}
})
</script>
</head>
<body>
</body>
</html>
使用 promise 方式
promise.html
<!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函数
//4. 如果请求失败, 调用reject函数
//5. 箭头函数体, 仍然是通过jquery发出ajax
let p = new Promise((resolve, reject) => {
//发出ajax
$.ajax({
url: "data/monster.json",
success(resultData) {//成功的回调函数
console.log("promise发出的第1次ajax monster基本信息=", resultData);
resolve(resultData);
},
error(err) {
//console.log("promise 1发出的异步请求异常=", err);
reject(err);
}
})
})
//这里我们可以继续编写请求成功后的业务
p.then((resultData) => {
//这里我们可以继续发出请求
//console.log("p.then 得到 resultData", resultData);
return new Promise((resolve, reject) => {
$.ajax({
url: `data/monster_detail_${resultData.id}.json`,
success(resultData) { //第2次ajax请求成功,回调函数
console.log("第2次ajax请求 monster的详细信息=", resultData);
//继续进行下一次的请求
resolve(resultData);
},
error(err) { //第2次ajax请求失败,回调函数
//console.log("promise2 发出的异步请求异常=", err);
reject(err);
}
})
})
}).then((resultData) => {
console.log("p.then().then(), resultData", resultData)
//即可以在这里发出第3次ajax请求=》 获取该妖怪的女友
return new Promise((resolve, reject) => {
$.ajax({
url: `data/monster_gf_${resultData.gfid}.json`,
success(resultData) { //第3次ajax请求成功,回调函数
console.log("第3次ajax请求 monster女友的详细信息=", resultData);
//继续进行下一次的请求
//resolve(resultData);
},
error(err) { //第2次ajax请求失败,回调函数
//console.log("promise2 发出的异步请求异常=", err);
//reject(err);
}
})
})
}).catch((err) => { //这里可以对多次ajax请求的异常进行处理
console.log("promise异步请求异常=", err);
})
</script>
</head>
<body>
</body>
</html>
示意图:
使用 promise 代码优化/重排 方式完成
<!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
//2. 获取monster_gf_2.json
get("data/monster.json").then((resultData) => {
//第1次ajax请求成功后的处理代码
console.log("第1次ajax请求返回数据=", resultData);
return get(`data/monster_detail_${resultData.id}.json`);
}).then((resultData) => {
//第2次ajax请求成功后的处理代码
console.log("第2次ajax请求返回数据=", resultData);
//return get(`data/monster_detail_${resultData.id}.json`);
return get(`data/monster_gf_${resultData.gfid}.json`);
}).then((resultData) => {
//第3次ajax请求成功后的处理代码
console.log("第3次ajax请求返回数据=", resultData);
//继续..
}).catch((err) => {
console.log("promise请求异常=", err);
})
</script>
</head>
<body>
</body>
</html>
get.js方法
/**
* 这里我们将重复的代码,抽出来,编写一个方法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 如果返回的是 Promise 对象,可以继续执行.then()
2 .then((data)=>{}) 的 data 数据是上一次正确执行后 resolve(data) 返回传入的
3 通过多级 .then() 可以对异步请求分层次请求,实现代码重排,代码逻辑更加清晰合理
4 通过多级 .then() 后面的 .catch((err) => {}) 可捕获发生异常,便于调试
综合代码
1. 分别使用 Jquery-Ajax 和 Promise 代码重排 完成如下功能, 发出 3 次 ajax 请求, 获取对应的数据, 注意体会 Promise 发出多次 Ajax 请求的方便之处
student.json
{
"id": 100,
"name": "xxx",
"class_id": 12
}
class_12.json
{
"id": 12,
"name": "java",
"student_num": 30,
"school_id": 9
}
school_9.json
{
"id": 9,
"name": "清华大学",
"address": "北京"
}
原始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({
url: "data/student.json",
success(data) {
console.log("第一次ajax请求数据=", data);
$.ajax({
url: `data/class_${data.class_id}.json`,
success(data) {
console.log("第2次ajax请求数据=", data);
$.ajax({
url: `data/school_${data.school_id}.json`,
success(data) {
console.log("第3次ajax请求数据=", data);
},
error(err) {
console.log("ajax请求发生异常:", err)
}
})
},
error(err) {
console.log("ajax请求发生异常:", err)
}
})
},
error(err) {
console.log("ajax请求发生异常:", err)
}
})
</script>
</head>
<body>
</body>
</html>
promise代码重排完成多次ajax请求
其中里面的get方法前面有代码
<!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" src="script/promise_utils.js"></script>
<script type="text/javascript">
//promise代码重排,完成多次ajax请求
get("data/student_100.json").then(data => {
console.log("第1次ajax请求, 返回的数据=", data);
return get(`data/class_${data.class_id}.json`);
}).then(data => {
console.log("第2次ajax请求, 返回的数据=", data);
return get(`data/school_${data.school_id}.json`);
}).then(data => {
console.log("第3次ajax请求, 返回的数据=", data);
}).catch(err => {
console.log("promise异步请求异常=", err);
})
</script>
</head>
<body>
</body>
</html>