2023/3/15日笔记

27 阅读1分钟

17-1、Promise是什么

认识 Promise

  • Promise 是异步操作的一种解决方案

什么时候使用 Promise

  • Promise 一般用来解决层层嵌套的回调函数 (回调地狱 callback hell) 的问题

代码案例

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>17-1、Promise是什么</title>
    <style>
        #box {
            width: 300px;
            height: 300px;
            background-color: red;
            transition: all 0.5s;
        }
    </style>
</head>

<body>
    <div id="box"></div>
    <script>
        // 认识 Promise
        // Promise 是异步操作的一种解决方案
        // 回调函数
        // document.addEventListener('click',() => {
        //     console.log('这里是异步的');
        // },false);
        // console.log('这里是同步的');

        // 2.什么时候使用 Promise
        // Promise 一般用来解决层层嵌套的回调函数 (回调地狱 callback hell) 的问题
        // 运动
        const move = (el, { x = 0, y = 0 } = {}, end = () => { }) => {
            el.style.transform = `translate3d(${x}px,${y}px,0)`;

            el.addEventListener('transitionend', () => {
                // console.log(end());
                end();
            }, false)
        }
        const boxEL = document.getElementById('box');

        document.addEventListener('click', () => {
            move(boxEL, { x: 150 }, () => {
                move(boxEL, { x: 150, y: 150 }, () => {
                    move(boxEL, { y: 150 }, () => {
                        // move(boxEL, { x: 0, y: 0 })
                        move(boxEL, {})
                    })
                })
            })
        }, false)
    </script>
</body>

</html>

17-2、Promise的基本用法

Promise 的状态

  • Promise 有 3 种状态,一开始是pending(未完成),执行resolve,变成 fulfilled(resolved),已成功
  • Promise 的状态一旦变化,就不会再改变了

代码案例

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>17-2、Promise的基本用法</title>
</head>

<body>
    <script>
        // 1.实例化构造函数生成实例对象
        // console.log(Promise);

        // Promise 解决的不是回调函数,而是回调地狱
        // const p = new Promise(() => { })

        // 2.Promise 的状态
        const p = new Promise((resolve, reject) => {
            // Promise 有 3 种状态,一开始是pending(未完成),执行resolve,变成 fulfilled(resolved),已成功
            // 执行 reject,变成 rejected,已失效

            // Promise 的状态一旦变化,就不会再改变了

            // pending -> fulfilled
            // resolve({username:'alex'});

            // pending -> rejected
            // reject('reason');
            reject(new Error('reason'));
        })
        console.log(p);

        // 3.then 方法
        p.then(() => {
            console.log('success');
        }, () => {
            console.log('error');
        });

        // 4.resolve 和 reject 函数的参数
        p.then((data) => {
            console.log('success',data);
        }, (err) => {
            console.log('error',err);
        });
    </script>
</body>

</html>

18-1、then()

什么时候执行

  • pending -> fulfilled 时,执行 then 的第一个回调函数
  • pending -> rejected 时,执行 then 的第二个回调函数

执行后的返回值

  • then 方法执行后返回一个新的 Promise

then 方法返回的 Promise 对象的状态改变

  • 在 then 的回调函数中,return 后面的东西,会用 Promise 包装一下
  • 默认返回的永远都是成功状态的 Promise 对象
  • 如果想失败,只能手写 Promise 对象
  • 默认返回值是 undefined

代码案例

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>18-1、then()</title>
</head>

<body>
    <script>
        // 1.什么时候执行
        // pending -> fulfilled 时,执行 then 的第一个回调函数
        // pending -> rejected 时,执行 then 的第二个回调函数

        // 2.执行后的返回值
        // then 方法执行后返回一个新的 Promise
        // const p = new Promise((resolve, reject) => {
        //     resolve();
        //     // reject();

        // });
        // const p2 = p.then(
        //     () => { },
        //     () => { },
        // ).then()
        // .then();
        // console.log(p, p2, p === p2);

        // 3.then 方法返回的 Promise 对象的状态改变

        const p = new Promise((resolve, reject) => {
            // resolve('succ');
            reject();

        });
        p.then(
            (data) => {
                console.log('success', data);
            },
            () => {
                console.log('err');

                // 在 then 的回调函数种,return 后面的东西,会用 Promise 包装一下
                // return undefined;
                // 等价于
                // return new Promise((resolve,reject) => {
                //     resolve(undefined);
                // });

                // return 123;

                // return new Promise((resolve,reject) => {
                //     resolve(123);
                // });

                // 默认返回的永远都是成功状态的 Promise 对象
                // 如果想失败,只能手写 Promise 对象

                return new Promise((resolve, reject) => {
                    reject('reason');
                });
            }
        ).then(
            (data) => {
                console.log('success2', data);
            },
            (err) => {
                console.log('err2', err);
                // 默认返回值是 undefined
                // return undefined

                // return new Promise((resolve,reject) => {
                //     resolve(undefined);
                // });
            }
        ).then(
            (data) => {
                console.log('success3', data);
            },
            (err) => {
                console.log('err3', err);
            }
        );
    </script>
</body>

</html>

18-2、Promise解决回调地狱

代码案例

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>18-2、Promise解决回调地狱</title>
    <style>
        .box {
            width: 300px;
            height: 300px;
            background-color: blue;
            transition: all 0.5s;
        }
    </style>
</head>

<body>
    <div class="box"></div>
    <script>
        const obox = document.querySelector('.box');
        const move = (el, { x = 0, y = 0 } = {}, end = () => { }) => {
            el.style.transform = `translate3d(${x}px,${y}px,0)`;

            el.addEventListener('transitionend', () => {
                end();
            }, false);
        };

        const movePromise = (el, point) => {
            return new Promise(resolve => {
                move(el, point, () => {
                    resolve();
                });
            });
        }

        document.addEventListener('click', () => {
            movePromise(obox, { x: 150 }).then(() => {
                return movePromise(obox, { x: 150, y: 150 }).then(() => {
                    return movePromise(obox, { y: 150 }).then(() => {
                        return movePromise(obox,{})
                    })
                })
            })
        }, false);



        // document.addEventListener('click', () => {
        //     move(obox, { x: 150 }, () => {
        //         move(obox, { x: 150, y: 150 }, () => {
        //             move(obox, { y: 150 }, () => {
        //                 move(obox, {});
        //             })
        //         })
        //     })
        // },false)

    </script>
</body>

</html>

18-3、catch()

有什么用

  • then()方法可以只处理成功状态
  • catch 专门用来处理 rejected(失败) 状态
  • catch 本质上是 then 的特例

基本用法

  • catch() 可以捕获他前面的错误
  • 一般总是建议,Promise 对象后面要跟 catch 方法,这样可以处理 Promise 内部发生的错误

代码案例

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>18-3、catch()</title>
</head>

<body>
    <script>
        // 1.有什么用
        // then()方法可以只处理成功状态
        // then(
        //     data =>{},
        //     err =>{},
        // );
        // then(data => {});

        // catch 专门用来处理 rejected(失败) 状态
        // catch 本质上是 then 的特例
        // then(null,err => {});

        // 2.基本用法
        new Promise((resolve, reject) => {
            // resolve(123);
            reject('reason');
        })
        .then(data => {
            console.log(data);
        })
        // .then(null,err => {
        //     console.log(err);
        // })
        .catch(err => { 
            console.log(err);

            // return undefined;
            // 在前面捕获了一个错误,但是自己却也生成了一个错误,所以需要再捕获一次
            throw new Error('reason');
        })
        .then(data => {
            console.log(data);
        }).catch(err => {
            console.log(err);
        });

        // catch() 可以捕获他前面的错误
        // 一般总是建议,Promise 对象后面要跟 catch 方法,这样可以处理 Promise 内部发生的错误
    </script>
</body>

</html>

18-4、finally()

什么时候执行

  • 当 Promise 状态发生变化时,不论如何变化都会执行,不变化不执行

本质

  • finally() 本质上是 then() 的特例

代码案例

<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>18-4、finally()</title>
</head>

<body>
    <script>
        // 1.什么时候执行
        // 当 Promise 状态发生变化时,不论如何变化都会执行,不变化不执行
        // new Promise((resolve,reject) => {
        //     // resolve(123);
        //     reject('reason');
        // })
        // .finally(data => {
        //     console.log(data);
        // })
        // .catch(err => {})

        // 2.本质
        // finally() 本质上是 then() 的特例

        new Promise((resolve, reject) => {
            // resolve(123);
            reject('reason');
        })
            .finally(data => {
                console.log(data);
            })
            .catch(err => { });
        // 等同于
        new Promise((resolve, reject) => {
            // resolve(123);
            reject('reason');
        }).then(result => {
            return result;
        }, err => {
            // throw err;
            return new Promise((resolve, reject) => {
                reject(err);
            })
        }).then(data => {
            console.log(data);
        }).catch(err => {
            console.log(err);
        })
    </script>
</body>

</html>