目录
(1) Ajax方式的异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,称为"Callback Hell" (回调地狱)。
(2) Promise即是异步编程的一种解决方案,早在 ECMAScript 2015 (ES6) 中便成为标准。
(3) 从语法层面讲,Promise是一个对象,用来获取异步操作的信息。
通过student和student_detail_1两个json文件来简单模拟测试数据;第一次请求得到student.json中保存的数据,第二次请求通过前一次请求得到的数据,进一步得到student_detail_1.json中保存的数据(即先得到student.json中的id属性,根据该属性进一步得到student_detail_1.json中的更多属性)。
student.json代码如下 :
- {
- "id" : 1,
- "name" : "Cyan"
- }
student_detail_1.json代码如下 :
- {
- "id" : 1,
- "name" : "Cyan",
- "age" : 21,
- "score" : 450
- }
traditional_ajax.html代码如下 :
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Traditional Asynchronoustitle>
-
- <script type="text/javascript" src="../script/jquery-3.7.0.min.js">script>
- <script type="text/javascript">
- /*
- PS : JQuery操作Ajax回顾 :
- $.ajax函数的常用参数如下———
- (1) url : 请求的地址
- (2) type : 请求的方式GET or POST
- (3) data : 发送到服务器端的数据,将自动转换为请求字符串格式
- (4) success : 成功的回调函数
- (5) dataType : 返回的数据类型,常用Json或text。
- */
- $.ajax({
- url:"../data/student.json",
- // type: ,
- // data: ,
- success:function (resultData) {
- console.log("The 1st request,and the student's basic information is :",resultData);
- //从第二次异步请求开始,已经出现了"ajax嵌套"
- $.ajax({
- url:`../data/student_detail_${resultData.id}.json`,
- success(resultData) {
- console.log("The 2nd request,and the student's detailed information is :",resultData)
- },
- error(errInfo) {
- console.log("Oh oh,Something bad happened:",errInfo);
- }
- })
- },
- error(errInfo) { //ES6新特性————对象的方法简写。
- console.log("Something bad happened:",errInfo);
- }
- })
- script>
- head>
- <body>
-
- body>
- html>
运行结果 :
数据部分仍然使用data包下的student.json和student_detail_1.json。
promise.html代码如下 :
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Promise Demonstrationtitle>
- <script type="text/javascript" src="../script/jquery-3.7.0.min.js">script>
- <script type="text/javascript">
- //1.首先请求data包下的student.json(需要创建一个Promise对象)
- //创建Promise对象时需要传入一个箭头函数
- //形参resolve表示请求成功的回调函数;形参reject表示请求失败的回调函数。
- //形参resolve和reject是约定俗成的,不固定,可以自由更改名称。
- let promise = new Promise((resolve,reject) => {
- //发出Ajax异步请求
- $.ajax({
- url:"../data/student.json",
- // type:
- // data:
- // dataType:
- success(resultData) {
- console.log("Promise's 1st request,and the student's basic information is :",resultData);
-
- //该方法将resultData参数传递到then()
- resolve(resultData);
- },
- error(errInfo) {
- // console.log("Promise's 1st request---Perhaps sth bad happened:",errInfo);
-
- //使用ES6---Promise提供的catch机制来统一处理异常
- reject(errInfo);
- }
- })
- })
-
- //2.第二次请求在这里执行!
- promise.then(resultData => { //箭头函数形参的简写
- // 调用链, 通过return将Promise对象返回给下一个调用者。
- return new Promise((resolve, reject) => {
- $.ajax({
- //url采用了模板字符串的形式
- url:`../data/student_detail_${resultData.id}.json`,
- success(resultData) {
- console.log("Promise's 2nd request,and the student's detailed information is :",resultData);
-
- /*
- 可以在第二次请求的success回调函数里,
- 继续使用resolve(resultData);发出第三次请求。
- */
- resolve(resultData);
- },
- error(errInfo) {
- // console.log("Promise's 2nd request---Perhaps sth bad happened:",errInfo);
- reject(errInfo);
- }
- })
- })
- }).then(resultData => {
- /*
- (1)此处输出的resultData,来自第二次Ajax请求的success中的"resolve(resultData);"
- (2)可以在这个then方法中,继续通过
- "return new Promise((resolve, reject) => { $.ajax({}) })"
- 的方式来发出第三次Ajax异步请求。
- (3)第三次Ajax异步请求,是基于第二次Ajax请求获取的数据resultData。
- */
- console.log("After 2nd request, THE resultData =",resultData);
- }).catch(errInfo => {
- console.log("U~ Promise's request---Perhaps sth bad happened:",errInfo);
- })
- script>
- head>
- <body>
-
- body>
- html>
运行结果 :
使用Primise方式代替传统Ajax方式发送多次异步请求之后,以“链式调用”代替了“嵌套调用”,可读性提升。
但仍然存在“代码臃肿”,“代码重复度高”的特点;因此,可以通过代码重排进行优化。
在data包下新建一个json文件,用来模拟student1的监护人的数据。
custodian_1.json代码如下 :
- {
- "id" : 1,
- "phonetic" : "/kʌˈstoʊdiən/",
- "father": "f1",
- "mother": "m1",
- "telephone": 5204505
- }
promise_EX.html代码如下 :
- html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>To Optimize Promisetitle>
- <script type="text/javascript" src="../script/jquery-3.7.0.min.js">script>
- <script type="text/javascript">
- /**
- * @function 将多次请求相似的代码封装到一个方法中
- * @param url : 请求的资源
- * @param data : 请求时携带的数据
- * @returns {Promise
} - */
- function getRequest(url, data) {
- return new Promise((resolve, reject) => {
- $.ajax({
- url:url,
- data:data,
- success(resultData) {
- resolve(resultData);
- },
- error(err) {
- reject(err);
- }
- })
- })
- }
-
- //1.第一次请求 --- 得到student.json中保存的数据
- getRequest("../data/student.json").then(resultData => {
- console.log("student =", resultData);
-
- //2.第二次请求 --- 得到student_detail_1.json中保存的数据
- return getRequest(`../data/student_detail_${resultData.id}.json`).then(resultData => {
- console.log("student_1 =", resultData);
-
- //3.第三次请求 --- 得到custodian_1.json中保存的数据
- return getRequest(`../data/custodian_${resultData.id}.json`).then(resultData => {
- console.log("custodian_1 =",resultData);
- })
- })
- }).catch(err => {
- console.log("Perhaps something bad happened:",err);
- })
- script>
- head>
- <body>
- body>
- html>
运行结果 :
System.out.println("END------------------------------------------------------------");