Promise

  |   0 评论   |   0 浏览

Promise

1.1 Promise基本介绍

  1. 传统的 Ajax 异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的 Callback Hell
  2. 为了解决上述的问题,Promise 对象应运而生,在 EMCAScript 2015 当中已经成为标准
  3. Promise 是异步编程的一种解决方案。
  4. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息
  5. Promise 也是 ES6 的新特性

Promise 是异步编程的一种解决方案, 可以解决传统 Ajax 回调函数嵌套问题

1.2 Promise 应用实例

1.需求分析/图解

需求: 演示 promise 异步请求使用(如图)

image-20220512221529134

2.代码实现

monster.json

{
  "id": 1,
  "name": "黑山老妖~"
}

monster_detail_1.json

{
  "id": 1,
  "address": "黑山洞",
  "skill": "无法无天-翻江倒海",
  "age": 500,
  "gfid": 2
}

monster_gf_2.json

{
  "name": "狐狸精",
  "age": 100
}

promise.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">

        //先请求到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);
                },
                error(err) {
                    //console.log("promise 1发出的异步请求异常=", err);
                    reject(err);
                }
            })
        })

        //这里我们可以继续编写请求成功后的业务
        p.then((resultData) => {
            //这里我们可以继续发出请求
            //console.log("p.then 得到 resultData", resultData);
            return new Promise((resolve, reject) => {
                $.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>

1.3 注意事项和使用细节

1.如果返回的是 Promise 对象,可以继续执行.then()

2.then((data)=>{}) 的 data 数据是上一次正确执行后 resolve(data) 返回传入的

3.通过多级.then() 可以对异步请求分层次请求,实现代码重排,代码逻辑更加清晰合理

4.通过多级.then() 后面的 .catch((err) => {}) 可捕获发生异常,便于调试