微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

2021-03-15ES6-promise

回调地狱

回调地狱: 因为js是单线程的, 有些时候为了代码功能需求,需要函数嵌套函数,当函数嵌套多层时,就会形成回调地狱

如何解决回调地狱: 通过Promise() 解决
Promise是异步编程的一种解决方

		//模拟异步操作
        // function fun1() {
        //     setTimeout(function() {
        //         console.log("setTimeout1");
        //     }, 1000)
        // }

        // function fun2() {
        //     setTimeout(function() {
        //         console.log('setTimeout2');
        //         fun1()
        //     }, 2000)
        // }

        // function fun3() {
        //     setTimeout(function() {
        //         console.log('setTimeout3');
        //     }, 2000)
        // }


        //回调地狱
        function fun() {
            setTimeout(function() {
                console.log(2);
                setTimeout(function() {
                    console.log(1);
                })
                setTimeout(function() {
                    console.log(3);
                })
            })
        }
        fun()
告白
function confession() {
            if (Math.random() > 0.5) {
                console.log("女孩同意");
                if (Math.random() > 0.5) {
                    console.log("父亲同意");
                    if (Math.random() > 0.5) {
                        console.log("叔叔同意");
                    } else {
                        console.log("叔叔拒绝");
                    }
                } else {
                    console.log("父亲拒绝");
                }
            } else {
                console.log("女孩拒绝");
            }
        }
        confession();

promise基础

Promise() 对象:
存在三种状态:
进行时 pending
成功 resolve
失败 reject
状态的改变 只能从 pending 转换为 resolve; 或者 从pending 转换为 reject; 如果处于pending状态,永远不知道下一步转换为什么状态

Promise() 接受一个函数作为参数; 函数存在两个参数(这两个参数是js原生提供的) 一个是resolve, 一个是reject

Promise()的执行机制:
如果Promise()执行成功,则会调用执行 resolve(); resolve()中的参数就是执行成功的结果,通过then() 进行接受, then() 参数是一个函数函数的参数就是 resolve传递传递出来的数据

如果Promise()执行失败, 则会调用执行 reject(); reject()中的参数就是执行失败的错误信息, 通过 catch()进行接受, catch的参数一个函数函数的参数 err 就是reject 传递出来的错误信息

官网的解说:
resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise()基本结构:

有了Promise对象,就可以将异步操作以同步操作的流程表达出来,避免了层层嵌套的回调函数; 因为这样, 可以通过Promise() 解决回调地狱的问题

 var p1 = new Promise(function(resolve, reject) {
            if (Math.random() > 0.5) {
                resolve();
            } else {
                reject();
            }
        })
        p1.then(function(data) {
            console.log('promise 成功执行了' + data);
        }).catch(function(err) {
            console.log('promise 执行失败' + err);
        })

promise解决上述回调地狱问题

function fun1() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log("输出1");
                    resolve();
                }, 1000)
            })
        }

        function fun2() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log("2");
                    resolve();
                }, 2000)
            })
        }

        function fun3() {
            return new Promise((resolve, reject) => {
                setTimeout(function() {
                    console.log('setTimeout3');
                    resolve();
                }, 2000)
            })
        }
        fun2().then(fun1).then(fun3)

try catch

try…catch 的作用是测试代码中的错误
js 的异常捕获

   try{
        // 代码测试
    }catch{
        // 异常捕获 
    }finally{
        // finally 使用较少
       // 无论代码是否出错,此处的代码始终执行 
    }

    try{
        // 代码测试
    }catch(err){
        // 异常捕获 
    }finally{
       // 无论代码是否出错,此处的代码始终执行 
    }

js的错误类型:

		1.SyntaxError(语法错误)  ***
        2.ReferenceError(引用错误)  ***
        3.RangeError(范围错误)
        4.TypeError(类型错误)  ***
        5.URLError(URL错误)
        6.EvalError(eval错误)
        7. Error(错误)
//  注意: !!! 如果不需要输出错误信息,catch 后不需要() 
        //  try-catch 语句
        try {
            console.log(a);
        } catch {
        //  一旦代码出错,自动执行catch语句,
            console.log("代码出错了");//代码出错了
        }


        // 如果需要输出错误信息,对错误进行处理; catch 需要() 并且需要传入一个参数err (就是错误信息) 
        try {
            console.log(a);
        } catch (err) {
            //  捕获 err 就是错误信息
            console.log(err); //ReferenceError: a is not defined at 05js的try-catch语句.html:51
        }
        //  finally 不管代码是否出错,都会执行
        try {
            // console.log(a);
            console.log(1);
        } catch (err) {
            console.log(err);
        } finally {
            //   finally此处的代码始终都会执行
            console.log("代码执行了");
        }

        // ReferenceError: a is not defined at 05js的try-catch语句.html:65
        // 代码执行了

        // 1
        // 代码执行了

promise.all

10个ajax请求 全部执行结束 然后在去做下一件事情 ; 如何判断10个请求都执行完成结束了呢?

Promise.all() 方法可以解决这个问题:
接受的参数是一个数组, 数组中的每个值是promise 实例对象, all()的状态是由参数的状态的决定 ; 所有的promise对象都成功则成功,有一个失败则失败

Promise.all()方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。(返回的结果是一个Promise()对象)

function fun1() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                        console.log("setTimeout1");
                        // resolve('setTimeout1 的 data');
                        reject("setTime1 第一个失败")
                    },
                    1000)
            })
        }

        function fun2() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log('setTimeout2');
                    resolve('setTimeout2 的 data2');
                }, 1500)
            })
        }

        function fun3() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log('setTimeout3');
                    // resolve('setTimeout3 的 data3');
                    reject('setTimeout3 失败了');
                }, 2000)
            })
        }
        //  Promise.all() 参数是一个数组, 数组中的每个值都是Ppromise()的实例对象, 
        const p = Promise.all([fun1(), fun2(), fun3()])
            //  p 的状态 有 fun1(), fun2(), fun3() 决定,只有fun1(), fun2(), fun3() 都是成功,则 p的 状态是 成功 fulfilled ; 如果  fun1(), fun2(), fun3() 存在一个失败,则 p的状态 是失败rejected
            // console.log(p);
        p.then((data) => {
            //  then()方法的回调函数的参数 是 所有 Promise()实例执行成功时传递的数据,自动把所有的数据放到一个数组中
            console.log(data);
        }).catch((err) => {
            //  catch() 方法 优先捕获失败的信息, 谁先失败 就捕获谁
            console.log(err);
            // console.log('三个函数都执行结束');
        }).finally(() => {
            console.log("代码始终都会执行");
        })

promise.race

Promise.race() 方法 的参数是一个数组, 数组中的每个值是 Promise() 实例对象; 最后返回一个新的Promise() 对象
哪个结果获得的快,就返回那个结果,不管结果本身是成功状态还是失败状态。

function fun1() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log('setTimeout1');
                    resolve('setTimeout1 的 data');
                    // reject('setTimeout1 第一个失败');
                }, 1000)
            })
        }

        function fun2() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log('setTimeout2');
                    // resolve('setTimeout2 的 data2');
                    reject('setTimeout2 的 失败');
                }, 1500)
            })
        }

        function fun3() {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    console.log('setTimeout3');
                    resolve('setTimeout3 的 data3');
                    // reject('setTimeout3 失败了');
                }, 2000)
            })
        }
        //  Promise.race() 方法 的参数是一个数组, 数组中的每个值是 Promise() 实例对象; 最后返回一个新的Promise() 对象
        //  状态 改变: fun1(), fun2(), fun3() 三个实例对象 谁的状态先改变(不管成功还是失败),则p的状态都会随之跟随改变   如果fun1(), fun2(), fun3() 三个实例对象 先改变的状态是成功,则成功,如果失败则失败
        //  
        const p = Promise.race([fun1(), fun2(), fun3()]);
        p.then(res => {
            console.log(res);
        }).catch(err => {
            console.log(err);

        })

async和await

回调地狱: 通过 Promise() 解决
Promise() 解决回调地狱会产生一个新的问题: 就是 Promise()的链式调用问题
async 函数一个异步操作, 返回的是一个Promise()对象
await 等待; 在 async函数中使用 通常情况下 await 后是一个Promise()对象, 如果不是,会自动转换为Promise()对象形式 Promise.resolve(100) 把数据传递出去s
async 和 await 结合使用 可以把异步的操作以同步的形式展示

// async function fun(val) {
    //     console.log(1);
    //     // return "hello"+val;
    // }
    // fun()

    async function fun() {
        console.log(1);
        //    通过return 传递结果(数据)
        //   通过 await 等待 fun2() 执行的结果
        //  可以是 Promise()对象
        let res = await fun2();
        //  也可以是具体的值
        let res2 = await 100;
        //  await 等待的结果 最终就是一个具体的值, 
        let res3 = await new Promise((resolve, reject) => {
            resolve('这是Promise对象')
        })
        console.log(res3);
        //  如果不需要使用结果, 可以直接单独的await 
        await fun2()

        return 'hello' + res + res2;
    }

    async function fun2() {
        console.log(2);
        return "word";
    }
    fun().then(res => {
            console.log(res);
        })
        //   不能单独在 async 外使用await  (await)
        // let result = await fun2();

    // let res = fun();
    // console.log(res);
    // res.then(data => {
    //     fun(data).then(res => {
    //         console.log(res);
    //     })
    // })

    // fun2().then(data => {
    //     fun(data).then(res => {
    //         console.log(res);
    //     })
    // })

promise和async的区别

function longTime(time) {
            return new Promise((resolve, reject) => {
                setTimeout(() => {
                    resolve(time + 500)
                }, time)
            })
        }
        //  三个函数 time1() ==> time2() ===> time3()  通过Promise() 实现
        function time1(n) {
            return longTime(n);
        }
        //回调函数多层嵌套
        // time1(500).then(res1 => {
        //         console.log(res1);
        //         time1(res1).then(res2 => {
        //             console.log(res2);
        //             time1(res2).then(res3 => {
        //                 console.log(res3);
        //             })
        //         })
        //     })
        // 1000
        // 1500
        // 2000

        // time1(500).then(res1 => {
        //     return time1(res1)
        // }).then(res2 => {
        //     // console.log(res2);
        //     return time1(res2);
        // }).then(res3 => {
        //     console.log(res3); //2000
        // })

        //  使用 async 函数实现
        // async function test(n) {
        //     let res = await longTime(n);
        //     // console.log(res);
        //     return res;
        // }
        // test(500).then(res1 => {
        //         console.log(res1);
        //         return longTime(res1)
        //     }).then(res2 => {
        //         console.log(res2);
        //         return longTime(res2);
        //     }).then(res3 => {
        //         console.log(res3);
        //     })
        // 1000
        // 1500
        // 2000

        //  如果存在三个函数
        async function time1(n) {
            return await longTime(n);
        }
        async function time2(n) {
            return await longTime(n);
        }
        async function time3(n) {
            return await longTime(n);
        }
        async function test(n) {
            let res1 = await time1(n);
            let res2 = await time2(res1);
            let res3 = await time3(res2);
            console.log(res3);
        }
        test(500); //2000

        // function time1(n) {
        //     return longTime(n);
        // }

        // function time2(n) {
        //     return longTime(n);
        // }

        // function time3(n) {
        //     return await longTime(n);
        // }
        // test().then(res => {})

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐