• 再谈promise


    promise反复学习总结就会深刻 提高;

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <title>再谈promise</title>
        </head>
        <body>
            <script type="text/javascript">
                /*
                    Promise 出现的原因: 例如ajax【根据第一个网络请求的结果,再去执行第二个网络请求】===> 此时造成回调地狱
                    后果:
                        1.代码臃肿
                        2.可读性差
                        3.耦合度过高,可维护性差
                        4.代码复用性差
                        5.容易滋生 bug
                        6.只能在回调里处理异常
                        
                    什么是 Promise? 
                         Promise 是异步编程的一种解决方案,比传统的异步解决方案【回调函数】和【事件】更合理、更强大。
                        
                        promise本身是同步的  promise的回调then/catch是异步的
                        async/await也是基于 Promise 实现的
                        async函数内部同步执行,await之间相当于.then。
                        async函数外部的调用异步执行
                    传统回调地狱版本:
                    请求1(function(请求结果1){
                        请求2(function(请求结果2){
                            请求3(function(请求结果3){
                                请求4(function(请求结果4){
                                    请求5(function(请求结果5){
                                        请求6(function(请求结果3){
                                            ...
                                        })
                                    })
                                })
                            })
                        })
                    })
                    
                    promise版本:
                    new Promise(请求1)
                        .then(请求2(请求结果1))
                        .then(请求3(请求结果2))
                        .then(请求4(请求结果3))
                        .then(请求5(请求结果4))
                        .catch(处理异常(异常信息))
                        
                    Promise常用的 API
                        Promise.prototype.then()
                        Promise.prototype.finally(): 不管 Promise 对象最后状态如何,都会执行的操作
                        Promise.all()
                        Promise.allSettled()
                        Promise.race(): Promise.race()方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例
                        Promise.any(): 该方法接受一组 Promise 实例作为参数,包装成一个新的 Promise 实例返回
                        Promise.resolve()
                        Promise.reject(): 返回一个新的 Promise 实例,实例的状态为rejected
                        Promise.try()
                        Promise.prototype.catch()
                        Promise.try就是模拟try代码块,就像promise.catch模拟的是catch代码块
                    Promise有三种状态, pending , resolved , rejected , 只能从等待态转为其他两种状态;
                    每次调用then方法,都会返回一个新的promise;
                    promise支持链式调用,内部原理采用的是发布订阅模式;
                    一定谨记,一个 Promise 对象有三个状态,并且状态一旦改变,便不能再被更改为其他状态!!!
                 
                */
                // 首先初始化一个 Promise 对象,可以通过两种方式创建  Promise构造函数【new Promise()】接受一个函数作为参数,该函数的两个参数分别是resolve和reject。它们是两个函数
                // resolve函数的作用是: 将Promise对象的状态从【未完成】变为【成功】(即从 pending => resolved)
                // reject函数的作用是: 将Promise对象的状态从【未完成】变为【失败】(即从 pending => rejected)
                function fn(resolve, reject) {
                    console.log('返回promise对象')
                    // resolve(1)
                }
                // 方式一
                const promise1 = new Promise(fn)
                console.log(promise1) // Promise {<pending>} 若是fn加上 resolve(1) 则 状态变为 Promise {<fulfilled>: 1}
                // 方式二
                const promise2 = Promise.resolve(fn)
                console.log(promise2) // Promise {<fulfilled>: ƒ}
    
                /*****************Promise.any() 与 Promise.race() 和 Promise.all() 和 Promise.allSettled()********************/
                // 只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态
                // Promise.any()跟Promise.race()方法很像,只有一点不同,就是不会因为某个 Promise 变成rejected状态而结束
                const q1 = new Promise((resolve, reject) => {
                    reject("失败");
                });
    
                const q2 = new Promise((resolve, reject) => {
                    setTimeout(resolve, 300, "后成功");
                });
    
                const q3 = new Promise((resolve, reject) => {
                    setTimeout(resolve, 100, "先成功");
                });
    
                const q4 = new Promise((resolve, reject) => {
                    setTimeout(resolve, 500, "最后成功");
                });
    
                Promise.any([q1, q2, q3]).then((res) => {
                    console.log(res); // 先成功  
                })
    
                Promise.race([q2, q3, q4]).then((res) => {
                    console.log(res); // 先成功  
                })
    
                Promise.all([q2, q3, q4]).then((res) => {
                    console.log(res); // ["后成功", "先成功", "最后成功"]  
                }).catch(e => console.log(e));
    
                const resolved = Promise.resolve(1);
                const rejected = Promise.reject(-1);
                const allSettledPromise = Promise.allSettled([resolved, rejected]);
                allSettledPromise.then(function(results) {
                    console.log(results); // [{status: 'fulfilled', value: 1},{status: 'rejected', reason: -1}]
                });
                // 总结
                // Promise.any()即使第一个返回的 promise 是失败的,Promise.any() 依然使用第一个成功状态的 promise 来返回
                // 这与使用首个(无论 rejected 还是 fullfiled)promise 来返回的 Promise.race() 相反
                // Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝
                // Promise.all(iterable) 方法返回一个 Promise 实例只要有其中一个promise实例是rejected,就会直接走catch方法,并且catch中只会返回第一个变成rejected的promise的错误
                // Promise.race()方法的参数与Promise.all()方法一样,如果不是 Promise 实例,就会先调用Promise.resolve()方法,将参数转为 Promise 实例,再进一步处理
                // Promise.all()无法确定所有请求都结束 Promise.allSettled()就很容易
    
                /****************************Promise.resolve()**************************************/
                // 需要将现有对象转为 Promise 对象,Promise.resolve()方法就起到这个作用
                const r1 = Promise.resolve('aa')
                console.log(r1, 'r1') // Promise {<fulfilled>: "aa"} "r1"
                // 等价于
                const r2 = new Promise(resolve => resolve('aa'))
                console.log(r2, 'r2') // Promise {<fulfilled>: "aa"} "r2"
                // Promise.resolve()参数的四种情况
                // 1.参数是一个 Promise 实例
                // 如果参数是 Promise 实例,那么Promise.resolve将不做任何修改、原封不动地返回这个实例
                // 2.参数是一个thenable对象
                let thenable = {
                    then: function(resolve, reject) {
                        resolve(666);
                    }
                };
                let promise = Promise.resolve(thenable);
                promise.then(function(res) {
                    console.log(res, 'res'); // 666
                });
                // 3.参数不是具有then()方法的对象,或根本就不是对象
                const p = Promise.resolve('Hello world');
                p.then(function(res) {
                    console.log(res) // Hello world
                });
                // 4.不带有任何参数
                setTimeout(function() {
                    console.log('3');
                }, 0);
    
                Promise.resolve().then(function() {
                    console.log('2');
                });
    
                console.log('1');
                // 输出的顺序为 1 2 3
    
                /****************************Promise.reject()**************************************/
                // Promise.reject()方法的参数,会原封不动地作为reject的理由,变成后续方法的参数
                const p1 = Promise.reject('出错了'); // Uncaught (in promise) 出错了
                console.log(p1, 'p1') // Promise {<rejected>: "出错了"} "p1"
                // 等同于
                const p2 = new Promise((resolve, reject) => reject('出错了'))
                p2.then(null, function(r) {
                    console.log(r, 'r') // 出错了 r
                });
    
                // 异步转同步 
                // 1.通过回调函数【回调函数就是将一个函数当作另一个主函数的参数来使用的函数】
                function test2() {
                    console.log('执行了test2');
                }
    
                function test1(cb) { //(主函数)
                    console.log('执行了test1');
                    setTimeout(function() {
                        cb();
                    }, 1000);
                }
                // 执行
                test1(test2);
                // 2 async-await async/await的作用就是使异步操作以同步的方式去执行
                // 一般情况下,async与await配合使用才能使异步操作同步化,await就是等待的意思,等待某一个函数执行完之后,后面的代码才能开始执行
                async function test() {
                    return '异步转同步'
                }
                console.log(test()); //Promise { '异步转同步' }
                test().then(res => {
                    console.log(res, 'res'); // 异步转同步 'res'
                })
    
                function fn1() {
                    return new Promise(resolve => {
                        setTimeout(function() {
                            msg = 'wait me 3000';
                            resolve(msg)
                        }, 3000);
                    });
                }
                async function fn2() {
                    var result = await fn1();
                    console.log(result);
                }
                fn2();
    
                // 使用Promise
                function fn3() {
                    return new Promise(function(resolve, reject) {
                        setTimeout(function() {
                            msg = 'wait me 3000';
                            resolve(msg);
                        }, 3000);
                    })
                }
                fn3().then(data => {
                    console.log(data)
                })
            </script>
        </body>
    </html>

     自己整理,请勿随意转载!!!!

  • 相关阅读:
    [SAP HANA] HANA 安装更新工具HDBLCM
    [SAP BASIS] [TMS] TMS相关的程序和后台作业
    [sap basis] [authorization trace] Disable/enable authorization trace
    IEEE 802.11 标准列表
    802.11 wireless 七
    802.11 wireless 六
    802.11 wireless 五
    802.11 wireless 四
    802.11 wireless 三
    802.11 wireless 二
  • 原文地址:https://www.cnblogs.com/lhl66/p/14450217.html
Copyright © 2020-2023  润新知