ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

回调地狱与promise

2021-11-24 13:31:45  阅读:142  来源: 互联网

标签:function 地狱 console log resolve promise return 回调


异步任务同步执行

        需求:假设我们现在有四个定时器,要求在第一个执行完毕后执行第二个,第二个执行完执行第三个...
        这个的常规做法就是嵌套...
setTimeout(function() {
            console.log('定时器1');
            setTimeout(function() {
                console.log('定时器2');
                setTimeout(function() {
                    console.log('定时器3');
                    setTimeout(function() {
                        console.log('定时器4');
                    }, 2000)
                }, 2000)
            }, 2000)
        }, 2000);

这样做是将异步代码变成了同步代码,等待两秒后执行下一个,如果每一层需要执行的代码量非常庞大,就会特别乱 不易阅读与维护,其实上面这个小例子就是回调地狱

promise:

promise 有三个状态:pending:进行中 fulfilled:已成功 rejected:已失败
promise的写法:通过 new Promise内置构造函数创建一个promise对象

  • 构造函数接收一个回调函数作为参数 回调函数需要传入两个参数: resolve 和 reject
    resolve将promise从进行中–已成功
    reject将promise从进行中–已失败
    注意:状态一旦改变 就不能再改回去

  • 捕获成功的状态 通过实例.then方法捕获

  • 捕获失败的状态 通过实例.then方法里面写逗号 另一个回调函数(与写catch是一样的效果)

let promise1 = new Promise(function(resolve, reject) {
            // resolve();
            // reject();
            resolve(x); // x 未定义 所以这是错误的 即使这是将promise变为成功状态 但依旧会走到catch中
            // reject(111);
        });

        promise1.then((value) => {
            console.log('已成功');
        }, (err) => {
            console.log(err); 
            /*
              ReferenceError: x is not defined
              at 06-4promise.html:28
              at new Promise (<anonymous>)
              at 06-4promise.html:25
              如果上面写的是reject(111) 那这里打印111
          */
        })

promise实例.then()方法返回值为一个promise对象 — 链式

let p1 = new Promise(function(resolve, reject) {
            resolve(111);
        })
        console.log(p1); // promise对象
        let p2 = p1.then((val) => {
            console.log(val); // 111
            // return x;
            return 666;
        })
        console.log(p2); // 也是一个新的promise对象 p1.then方法的调用结果就是一个promise对象
        p2.then((val) => {
            console.log(val); // undefined 因为p2没有resolve结果 那就默认为undefined 如果需要给p2抛出一些值 在p2.then中捕获的话 则需要在p1.then的结果中写return
        }, (err) => {
            console.log(err);
        });

解决回调地狱

let p1 = new Promise(function(resolve, reject) {
            resolve(111);
        })
        console.log(p1); // promise对象
        let p2 = p1.then((val) => {
            console.log(val); // 111
            // return x;
            return 666;
        })
        console.log(p2); // 也是一个新的promise对象 p1.then方法的调用结果就是一个promise对象
        p2.then((val) => {
            console.log(val); // undefined 因为p2没有resolve结果 那就默认为undefined 如果需要给p2抛出一些值 在p2.then中捕获的话 则需要在p1.then的结果中写return
        }, (err) => {
            console.log(err);
        });

        /* 
            promise实例.then()方法返回值为一个promise对象 在then中return的值 将作为下一个promise对象捕获的值
            p1.then((v) => {
                console.log(v); // 111
                return 999;
            }).then((v) => {
                console.log(v); // 999
            }) 
        */

        let pro1 = new Promise((resolve, reject) => {
            setTimeout(function() {
                console.log('函数1');
                resolve(); // 2000ms过后让当前pro1的状态变为成功
            }, 2000)
        })
        pro1.then((val) => {
            console.log(val); // udnefined
            return new Promise((resolve, reject) => { // 将下一个promise对象的then中能捕获的值设置为一个新的promise对象的结果 promise一旦创建就开始执行 2000ms后 resolve变为成功的状态 但未抛出值 所以这个新的promise对象的结果为undefined 并且通过return 返回出去 那么下一次then中获取到的val为undefined 
                setTimeout(function() {
                    console.log('函数2');
                    resolve(); 
                }, 2000)
            })
        }).then((val) => {
            console.log(val); // undefined pro1执行完毕时,才会返回新promise对象进行执行 意味着 这个then一旦捕获就说明函数2的定时器执行完毕
            return new Promise((resolve, reject) => {
                setTimeout(function() {
                    console.log('函数3');
                    resolve();
                }, 2000)
            })
        })

理解

  1. pro1创建时,函数1 的定时器就执行了,此时打印函数1, 然后resolve
  2. resolve后 pro1.then()被触发 return一新promise的执行结果 新promise开始被创建执行 输出函数2 然后resolve
  3. resolve后 由于pro1.then方法本就会返回一个新的promise对象 所以可以继续.then 这个.then中捕获的是上一次.then的return值,上一次return值是promise 这个promise创建便执行 resolve为空 所以 第二次.then中捕获的val为undefined, 紧接着 又一次return一个新promise的执行结果 新promise开始被创建执行 输出函数3

综合

<script>
        const p1 = new Promise(function(resolve, reject) {
            setTimeout(function() {
                console.log('定时器1');
                resolve();
            }, 2000);
        });

        function p2() {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    console.log('定时器2');
                    resolve();
                }, 2000);
            });
        }

        function p3() {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    console.log('定时器3');
                    resolve();
                }, 2000);
            });
        }

        function p4() {
            return new Promise(function(resolve, reject) {
                setTimeout(function() {
                    console.log('定时器4');
                    resolve();
                }, 2000);
            });
        }

        p1.then(() => {
            return p2();
        }).then(() => {
            return p3();
        }).then(() => {
            return p4();
        })
    </script>

标签:function,地狱,console,log,resolve,promise,return,回调
来源: https://blog.csdn.net/weixin_43174759/article/details/121513154

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有