Promise--代码实现-- ajax 传统方式和 promise 方式和 promise 代码优化/重排 方式的对比--综合代码示例

简介: Promise--代码实现-- ajax 传统方式和 promise 方式和 promise 代码优化/重排 方式的对比--综合代码示例

Promise

Promise 基本介绍


1. 传统的 Ajax 异步调用在需要多个操作的时候,会导致多个回调函数嵌套,导致代码不够直观,就是常说的 Callback Hell


2. 为了解决上述的问题,Promise 对象应运而生,在 EMCAScript 2015 当中已经成为标准


3. Promise 是异步编程的一种解决方案。


4. 从语法上说,Promise 是一个对象,从它可以获取异步操作的消息


5. Promise 也是 ES6 的新特性,因为比较重要,老师单独拉出来讲

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


Promise 应用实例

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

代码实现

monster.json

{

       "id": 1,

       "name": "黑山老妖"

}

monster_detail_1.json

{

       "address": "阴曹地府-黑山",

       "skill": "翻江倒海功",

       "age": 800

}

先使用 ajax 传统方式完成, 问题分析(出现回调函数嵌套)

ajax.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax多次请求</title>
    <!--引入jquery-->
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <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
                        //$.ajax
                        //$.ajax
                    },
                    error(err) { //出错的回调函数
                        console.log("出现异常=", err);
                    }
                })
            },
            error(err) {
                console.log("出现异常=", err);
            }
        })
    </script>
</head>
<body>
</body>
</html>

使用 promise 方式

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>

get.js方法

/**
 * 这里我们将重复的代码,抽出来,编写一个方法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 如果返回的是 Promise 对象,可以继续执行.then()

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

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

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

综合代码

1. 分别使用 Jquery-Ajax 和 Promise 代码重排 完成如下功能, 发出 3 次 ajax 请求, 获取对应的数据, 注意体会 Promise 发出多次 Ajax 请求的方便之处

student.json

{

       "id": 100,

       "name": "xxx",

       "class_id": 12

}

class_12.json

{

 "id": 12,

 "name": "java",

 "student_num": 30,

 "school_id": 9

}

school_9.json

{

 "id": 9,

 "name": "清华大学",

 "address": "北京"

}

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>jquery-ajax</title>
    <script type="text/javascript" src="script/jquery-3.6.0.min.js"></script>
    <script type="text/javascript">
        //思路
        $.ajax({
            url: "data/student.json",
            success(data) {
                console.log("第一次ajax请求数据=", data);
                $.ajax({
                    url: `data/class_${data.class_id}.json`,
                    success(data) {
                        console.log("第2次ajax请求数据=", data);
                        $.ajax({
                            url: `data/school_${data.school_id}.json`,
                            success(data) {
                                console.log("第3次ajax请求数据=", data);
                            },
                            error(err) {
                                console.log("ajax请求发生异常:", err)
                            }
                        })
                    },
                    error(err) {
                        console.log("ajax请求发生异常:", err)
                    }
                })
            },
            error(err) {
                console.log("ajax请求发生异常:", err)
            }
        })
    </script>
</head>
<body>
</body>
</html>

promise代码重排完成多次ajax请求

其中里面的get方法前面有代码

<!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" src="script/promise_utils.js"></script>
    <script type="text/javascript">
        //promise代码重排,完成多次ajax请求
        get("data/student_100.json").then(data => {
            console.log("第1次ajax请求, 返回的数据=", data);
            return get(`data/class_${data.class_id}.json`);
        }).then(data => {
            console.log("第2次ajax请求, 返回的数据=", data);
            return get(`data/school_${data.school_id}.json`);
        }).then(data => {
            console.log("第3次ajax请求, 返回的数据=", data);
        }).catch(err => {
            console.log("promise异步请求异常=", err);
        })
    </script>
</head>
<body>
</body>
</html>

 


目录
相关文章
|
6天前
|
前端开发
用Promise对象实现的 Ajax
用Promise对象实现的 Ajax
10 0
|
6天前
|
存储 前端开发
PROMISE解决AJAX中的串行和并行
PROMISE解决AJAX中的串行和并行
31 0
|
6天前
|
前端开发 API
用promise封装ajax
用promise封装ajax
27 0
|
6月前
|
前端开发 JavaScript API
Promise封装Ajax请求
Promise封装Ajax请求
30 0
|
9月前
|
存储 前端开发
Promise 解决AJAX中的串行并行
Promise 是个好东西!
85 0
|
10月前
|
XML JSON 前端开发
Ajax、Promise、Axios前端三剑客
Ajax、Promise、Axios前端三剑客
|
11月前
|
JSON 前端开发 JavaScript
【JavaScript】Promise(一) —— 理解和使用(是什么、怎么使用、与 Ajax 配合使用、涉及的API)
【JavaScript】Promise(一) —— 理解和使用(是什么、怎么使用、与 Ajax 配合使用、涉及的API)
|
前端开发
ES6 从入门到精通 # 18:使用 Promise 封装 ajax
ES6 从入门到精通 # 18:使用 Promise 封装 ajax
106 0
ES6 从入门到精通 # 18:使用 Promise 封装 ajax
|
前端开发
04 Promise的理解(Ajax)
Promise的理解(Ajax)
04 Promise的理解(Ajax)
|
XML JSON 前端开发
逐步了解Ajax和Promise
逐步了解Ajax和Promise
171 0