ES6 Promise 详解

目录

一、Promise基本介绍

二、Promise实现多次请求

[1.传统Ajax方式实现多次请求 :](#1.传统Ajax方式实现多次请求 :)

[1.1 json数据准备](#1.1 json数据准备)

[1.2 JQuery操作Ajax](#1.2 JQuery操作Ajax)

[2.使用ES6新特性Promise方式 :](#2.使用ES6新特性Promise方式 :)

三、Promise代码重排优化

[1.问题分析 :](#1.问题分析 :)

[2.代码优化 :](#2.代码优化 :)

[2.1 数据准备](#2.1 数据准备)

[2.2 代码重排](#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代码如下 :

javascript 复制代码
{
  "id" : 1,
  "name" : "Cyan"
}

student_detail_1.json代码如下 :

javascript 复制代码
{
  "id" : 1,
  "name" : "Cyan",
  "age" : 21,
  "score" : 450
}

1.2 JQuery操作Ajax

traditional_ajax.html代码如下 :

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代码如下 :

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代码如下 :

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

2.2 代码重排

promise_EX.html代码如下 :

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------------------------------------------------------------");

相关推荐
霸气小男几秒前
react + antDesign封装图片预览组件(支持多张图片)
前端·react.js
susu10830189111 分钟前
前端css样式覆盖
前端·css
学习路上的小刘2 分钟前
vue h5 蓝牙连接 webBluetooth API
前端·javascript·vue.js
&白帝&3 分钟前
vue3常用的组件间通信
前端·javascript·vue.js
小白小白从不日白14 分钟前
react 组件通讯
前端·react.js
陈大爷(有低保)18 分钟前
UDP Socket聊天室(Java)
java·网络协议·udp
罗_三金24 分钟前
前端框架对比和选择?
javascript·前端框架·vue·react·angular
Redstone Monstrosity31 分钟前
字节二面
前端·面试
kinlon.liu31 分钟前
零信任安全架构--持续验证
java·安全·安全架构·mfa·持续验证
东方翱翔38 分钟前
CSS的三种基本选择器
前端·css