Promise

本文介绍了JavaScript中的Promise,用于解决回调地狱问题。Promise是一个构造函数,通过new关键字实例化,有三种状态:pending、fulfilled和rejected。通过then()和catch()方法处理Promise的状态改变和结果。此外,文章还探讨了await表达式在async函数中的应用,以及如何用async封装AJAX来进一步优化异步代码。

一 、回调地狱

 什么是回调地狱

 在回调函数中嵌套回调 回调地狱就是为是实现代码顺序执行而出现的一种操作, 它会造成我们的代码可读性非常差, 后期不好维护。

 setTimeout(function() {
            console.log('first');
            setTimeout(function() {
                console.log('second');
                setTimeout(function() {
                    console.log('three');
                    // .........
                }, 1000)
            }, 1000)
        }, 1000)

二 、 Promise

Promise是一个构造函数,通过new关键字实例化对象 

语法:

new  Promise((resovle,reject)=>{})

 Promise接收一个函数作为参数

 在参数函数中接收两个参数

 resolve :成功函数

 reject  :失败函数

 const p = new Promise((resolve, reject) => {})

  Promise实例

        有两个属性

        state:状态

        第一种状态  pending(准备,待解决,进行中)

        

        第二种状态  fulfilled(已完成,成功)

 

        第三种状态  rejected(已拒绝,失败)

        result: 结果

 Promise状态的改变

        通过调用resolve()resject()改变当前Promise对象的状态

        promise改变的状态是一次性的

 const p = new Promise((resolve, reject) => {
            reject() //调用函数 可以使当前promise对象的状态改为 rejected
        })
        console.log(p); //rejected

  

 const p = new Promise((resolve, reject) => {

            resolve()//调用函数 可以使当前promise对象的状态改为 resolve

        })
        console.log(p); //resolve

      

Promise的结果

 let p = new Promise((resolve, reject) => {
            // 通过调用resolve,传递参数,改变 当前Promise对象的结果
            // resolve('成功')
            reject('失败的结果')
        })
        console.dir(p) //Promise的结果为  失败的结果

 Promise的方法

    then()方法函数

    参数

    1.是一个函数 (当Promise的状态时fulfilled时执行

    2.还是一个函数 (当Promise的状态时rejected时执行

    返回值:是一个Promise对象

    在then方法的参数的函数中  通过形参使用Promise对象的结果

 const p = new Promise((resolve, reject) => {
            reject('失败的结果')
                // resolve('成功的结果')
        })
        p.then((value) => {
            // 当Promise的状态时fulfilled时执行
            console.log('成功时调用', value);
        }, (err) => {
            // 当Promise的状态时rejected时执行
            console.log('失败时调用', err)
        })
        console.dir(p);

then()方法返回一个新的Promise实例
他的状态是pending
链式操作
因为then()方法的返回值也是一个Promise

所以then()后面还可以跟then
这种情况被称为链式操作

const p = new Promise((resolve, reject) => {
            reject('失败的结果')

        })
        const t = p.then((value) => {

            console.log('成功时调用', value);
        }, (err) => {

            console.log('失败时调用', err)
        })
        console.dir(t);

返回实例的状态改变

Promise的状态不改变 不会执行then里的方法
 

      const p = new Promise((res, rej) => {
            res()
        })
        const t = p.then(value => {
            console.log('成功');
            // 如果这里的代码出错 会将t实例的状态改成rejected
            // 如果在then方法的第一个参数函数中出现代码错误 会将返回的Promise实例改为rejected状态
            console.log(a);
        }, rea => {
            console.log('失败');
        })
        t.then(value => {
            console.log('成功', value);
        }, rea => {
            console.log('失败', rea);
        })

Catch()方法

cathch中的参数函数 在什么时候被执行

1.当Promise的状态改为rejected时,被执行

2.当Promise的执行体中出现代码错误也会被执行

 const p = new Promise((res, rej) => {
            // rej()
            // console.log(a);
            throw new Error('出错了')
        });
        
        p.catch((rea) => {
            console.log('失败', rea);
        })
        console.log(p)

Promise常见写法

 new Promise((res, rej) => {
            rej(11)
        }).then(value => {
            // 成功时被执行
            console.log('成功了');
        }).catch(reason => {
            // 出错时被执行
            console.log('失败了');
        })

解决回调地狱

 // 回调地狱
        // setTimeout(function() {
        //     console.log('first');
        //     setTimeout(function() {
        //         console.log('second');
        //         setTimeout(function() {
        //             console.log('three');
        //             // .........
        //         }, 1000)
        //     }, 1000)
        // }, 1000)

        // promise 写法
        new Promise((res, rej) => {
            setTimeout(() => {
                console.log(111);
                res()
            }, 1000)
        }).then(() => {
            return new Promise((res, rej) => {
                console.log(222);
                res()
            }, 4000)
        }).then(() => {
            return new Promise((res, rej) => {
                setTimeout(() => {
                    console.log(333);
                    res()
                }, 3000)
            })
        })

await表达式


await表达式一般为promise对象,但也可以是其他的值
如果表达式是其他值 直接将此值作为await的返回值
注意 await必须在async函数中 但async函数中可以没有await
如果await的Promise失败了 就会抛出异常 需要通过try...catch捕获处理

async function main() {
            let p = new Promise((resolve, reject) => {
                    // resolve('ok')
                    reject('Error')
                })
                //1.右侧为Promise 的情况
                // let res = await p
                // console.log(res);
                // 右侧为其他类型的数据
                // let res2 = await 20
                // console.log(res2);
                // 如果Promise是失败的状态
            try {
                let res3 = await p;
            } catch (e) {
                console.log(e);
            }
        }
        main()

用async封装AJAX

 <button>点击获取</button>
    <script>
        // 用async封装AJAX
        let btn = document.querySelector('button')

        function mainAJAX(url) {
            return new Promise((res, rej) => {
                const xhr = new XMLHttpRequest();
                xhr.open('get', url)
                xhr.send()
                xhr.onreadystatechange = () => {
                    if (xhr.readyState === 4) {
                        if (xhr.status >= 200 && xhr.status < 300) {
                            res(xhr.response)
                        } else {
                            rej(xhr.readyState)
                        }
                    }
                }
            })
        }

        btn.addEventListener('click', async() => {
            try {
                let data = await mainAJAX('https://api.apiopen.top/api/getHaoKanVideo?page=0&size=2')
                console.log(data);
            } catch (e) {
                console.log(e);
            }
        })
    </script>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值