Promise–ES6 的新特性
介绍
- 1.传统的 Ajax 异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的 Callback Hell
代码举例
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>//导入jquery <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 },error(err) { //出错的回调函数 console.log("出现异常=", err); } }) },error(err) { console.log("出现异常=", err); } })
- 2.为了解决上述的问题,Promise 对象应运而生,在 EMCAScript 2015 当中已经成为标准
- 3.Promise 是异步编程的一种解决方案。
- 4.从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
解决方式
使用 promise 方式完成
<script type="text/javascript" src="script/jquery-3.6.0.min.js"></script> <script type="text/javascript"> //先请求到 monster.json //1. 创建 Promise 对象,构造函数传入一个箭头函数 let p = new Promise((resolve, reject) => { // (resolve, reject) 参数列表 //箭头函数体通过 jquery 发出 ajax请求 $.ajax({ //data/monster.json引入json文件 url: "data/monster.json", success(resultData) {//成功的回调函数,把获取的数据传给下一次请求 console.log("promise 发 出的 第 1 次 ajax monster 基 本 信 息 =resultData); resolve(resultData);// 如果请求成功, 调用 resolve 函数 },error(err) { //console.log("promise 1 发出的异步请求异常=", err); reject(err);//如果请求失败, 调用 reject 函数 } }) }) //编写请求成功后的业务 p.then((resultData) => { //这里我们可以继续发出请求 //console.log("p.then 得到 resultData", resultData); return new Promise((resolve, reject) => { //返回一个新的promise对象 //重新发起请求 $.ajax({ url: `data/monster_detail_${resultData.id}.json`, success(resultData) //第 2 次 ajax 请求成功,回调函数,把获取的数据传给下一次请求 { //${resultData.id}动态获取数据id 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 请求=》 获取该json文件需要的信息 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 代码优化/重排
<title>promise 代码重排</title> <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script> <script type="text/javascript"> /** * 这里我们将重复的代码,抽出来,编写一个方法 get * * url ajax 请求的资源 * data ajax 请求携带的数据 * {Promise<unknown>} */ function get(url, data) {//传入请求的资源和需要携带的数据 return new Promise((resolve, reject) => { $.ajax({//发送jQuery请求 url: url, data: data, success(resultData) { resolve(resultData);// ajax 请求成功,回调函数 }, error(err) { reject(err);//ajax 请求失败,回调函数 } }) } )} //需求: 完成 //1. 先获取存放数据的json文件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_gf_${resultData.gfid}.json`); }).then((resultData) => { //第 3 次 ajax 请求成功后的处理代码 console.log("第 3 次 ajax 请求返回数据=", resultData); //继续.. }).catch((err) => {//对多次 ajax 请求的异常进行处理 console.log("promise 请求异常=", err); }) </script>
注意事项和使用细节
1.如果请求成功返回的是 Promise 对象,可以继续执行.then() 。
2..then((data)=>{}) 的 data 数据是上一次正确执行后 resolve(data) 返回传入的。
3.通过多级.then() 可以对异步请求分层次请求,实现代码重排,代码逻辑更加清晰合理,看起来也更加直观。
4.通过多级.then() 后面的 .catch((err) => {}) 可捕获发生异常,便于调试。