一、Promise 基本介绍
1. 传统的 Ajax 异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的Callback Hell
2. 为了解决上述的问题,Promise对象应运而生,在 EMCAScript 2015当中已经成为标准
3. Promise 是异步编程的一种解决方案。
4. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
5. Promise 也是 ES6 的新特性,因为比较重要
6. 一句话: Promise 是异步编程的一种解决方案, 可以解决传统 Ajax 回调函数嵌套问题
二、promise实例
jquery 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/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完成多次请求
<!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);//p.thend的前置
},
error(err) {
//console.log("promise 1发出的异步请求异常=", err);
reject(err);
}
})
})
//这里我们可以继续编写请求成功后的业务
p.then((resultData) => {
//这里我们可以继续发出请求
console.log("p.then 得到 resultData", resultData);
return new Promise((resolve, reject) => {
console.log(`data/monster_detail_${resultData.id}.json`),
$.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>
课后作业
<!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_100.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>
<!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>