ES6 Promise 详解

目录

一、Promise基本介绍

二、Promise实现多次请求

        1.传统Ajax方式实现多次请求 : 

            1.1 json数据准备

            1.2 JQuery操作Ajax

        2.使用ES6新特性Promise方式 : 

三、Promise代码重排优化

        1.问题分析 : 

        2.代码优化 : 

            2.1 数据准备

            2.2 代码重排


一、Promise基本介绍

        (1) Ajax方式的异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,称为"Callback Hell" (回调地狱)。
        (2) Promise即是异步编程的一种解决方案,早在 ECMAScript 2015 (ES6) 中便成为标准。
        (3) 从语法层面讲,Promise是一个对象,用来获取异步操作的信息


二、Promise实现多次请求

        1.传统Ajax方式实现多次请求 : 

            1.1 json数据准备

                通过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
}

            1.2 JQuery操作Ajax

                traditional_ajax.html代码如下 : 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Traditional Asynchronous</title>
    <!-- 此处的src使用了相对路径。 -->
    <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>

                运行结果 : 

        2.使用ES6新特性Promise方式 : 

                数据部分仍然使用data包下的student.json和student_detail_1.json。
                promise.html代码如下 : 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Promise Demonstration</title>
    <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>

                运行结果 :


三、Promise代码重排优化

        1.问题分析 : 

        使用Primise方式代替传统Ajax方式发送多次异步请求之后,以“链式调用”代替了“嵌套调用”,可读性提升。

        但仍然存在“代码臃肿”,“代码重复度高”的特点;因此,可以通过代码重排进行优化

        2.代码优化 : 

            2.1 数据准备

                在data包下新建一个json文件,用来模拟student1的监护人的数据。
                custodian_1.json代码如下 : 

{
  "id" : 1,
  "phonetic" : "/kʌˈstoʊdiən/",
  "father": "f1",
  "mother": "m1",
  "telephone": 5204505
}

            2.2 代码重排

                promise_EX.html代码如下 : 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>To Optimize Promise</title>
    <script type="text/javascript" src="../script/jquery-3.7.0.min.js"></script>
    <script type="text/javascript">
        /**
         * @function 将多次请求相似的代码封装到一个方法中
         * @param url : 请求的资源
         * @param data : 请求时携带的数据
         * @returns {Promise<unknown>}
         */
        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------------------------------------------------------------");