• 16-实现一个Promise.all 和 Promise.race


    思路:首先明白Promise.all的用法

    1:promise.all可以接受一个由promise数组作为参数,并且返回一个promise实例,

    2:promise.all([a,b,c...]).then方法之后的结果是一个数组,返回的数组是参数中依次执行的返回值

    3: 参数中的promise有一个失败则全部失败

    <!DOCTYPE html>
    <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>Document</title>
    </head>
    
    <body>
    
    </body>
    
    </html>
    <script>
        // 检测传入的是不是promise对象
        function isPromise(fun) {
            return typeof fun.then === 'function'
        }
    
        var p1 = new Promise((reslove, reject) => {
            setTimeout(() => {
                reslove('p1')
            }, 1000)
        })
        var p2 = new Promise((reslove, reject) => {
            reslove('p2')
        })
        var p3 = 123456;
        var p4 = function() {
                return new Promise((reslove, reject) => {
                    reject(new Error('我是一个错误'))
                })
            }
            // let res1 = isPromise(p1);
            // console.log(res1);
        Promise.myAll = function(arr) {
            return new Promise((reslove, reject) => {
                let count = 0;
                let resultArr = []; //存放传入的promise数组中每个promise执行结果的数组
    
                function sortFn(index, value) {
                    // 每次执行+=1,用于计数
                    count += 1;
                    // resultArr不能直接push到数组中value的值,如果value是个数字,会排在第一位,影响顺序
                    // 通过传进来的下标去指定位置,这样顺序就是我们想要的,极好!
                    resultArr[index] = value;
                    // 如果都成功了就把结果输出出去
                    if (count === arr.length) {
                        // console.log(resultArr, "结果");
                        reslove(resultArr)
                    }
                }
    
                // 遍历传进来的promise数组
                for (let i = 0; i < arr.length; i++) {
                    let cur = arr[i];
                    // 如果数组中当前的这一项是promise,那么就执行这个promise函数
                    // 并且把执行结果(当前这个promise的索引和结果作为参数传递出去)
                    if (isPromise(cur)) {
                        cur.then(res => {
                                sortFn(i, res);
                            }, reject) //reject就是外层的那个reject,因为只要有一个错误,就抛出
                    }
                    // 如果不是个promise函数,那么就把当前这一项的索引和其本身传递出去
                    else {
                        sortFn(i, cur);
                    }
                }
            })
        }
    
        Promise.myAll([p1, p2, p3, p4()]).then(res => {
                console.log(res);
            }, err => {
                console.log(err);
            })
            // 用.catch捕获,也可以向上面那样用then的第二个参数捕获错误
            // .catch(err => {
            //     console.log(err);
            // })
    </script>

    黄色标记get到思想:

    1.为了使循环中的结果添加到newArr新数组中,正常情况下我们会用newArr.push的情况。但是如果传入的数组中不是promise对象,而是一个数字,比如123456,那么最后这个输出这个数组的顺序就变成了数字排在了前面,不符合我们想要的Promise.all的输出顺序。

    2.所以我们需要手动保存当前循环中的索引,在上面newArr添加的时候,newArr[index] =value,我们通过存的索引,用数组的下标索引的方式去添加,这样就能保证添加顺序了。


     思路:Promise.race的用法:

    1.Promise.race()里面也是放了一个数组,数组里面的谁快,谁先执行,执行的结果就是当下这个Promise.race([]).then(res) 这个res结果

    2.不论数组里的结果成功还是失败,返回最快的那个结果。

    <!DOCTYPE html>
    <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>Document</title>
    </head>
    
    <body>
    
    </body>
    
    </html>
    <script>
        var p1 = new Promise((reslove, reject) => {
            setTimeout(() => {
                reslove('p1')
            }, 1000)
        })
        var p2 = new Promise((reslove, reject) => {
            setTimeout(() => {
                reslove('p2')
            }, 500)
        })
        var p3 = 123456;
        var p4 = new Promise((reslove, reject) => {
            setTimeout(() => {
                reject(new Error('这是一个错误'))
            }, 100)
        })
        var p5 = new Promise((reslove, reject) => {
            reslove('p5')
        })
    
        function isPromise(fun) {
            return typeof fun.then === 'function';
        }
    
        Promise.myRace = function(arr) {
            return new Promise((reslove, reject) => {
                for (let i = 0; i < arr.length; i++) {
                    let cur = arr[i];
                    if (isPromise(cur)) {
                        cur.then(res => {
                            // 谁先执行了,就把结果传出去
                            reslove(res)
                        }, reject)
                    } else {
                        reslove(cur)
                    }
                }
            })
        }
    
        Promise.myRace([p1, p2, p3, p4, p5]).then(res => {
                console.log(res);
            }, err => {
                console.log(err);
            })
            // 第二种写法:在外面调用catch
            // .catch(err => {
            //     console.log(err);
            // })
    
    
        // Promise.race([p1, p2, p3, p4, p5]).then(res => {
        //     console.log(res, '???');
        // }, err => {
        //     console.log(err);
        // })
    </script>

    一句话:在传入数组的循环中,执行每一项,谁最快有结果,就直接reslove把结果传递出去。

  • 相关阅读:
    一个重构眼中的“项目管理”
    vim显示行号、语法高亮、自动缩进的设置
    python中的try/except/else/finally语句--自我小结
    python 列表函数
    python异常处理
    gerrit使用总结
    数据访问对象模式
    组合实体模式
    业务代表模式
    MVC模式
  • 原文地址:https://www.cnblogs.com/haoqiyouyu/p/14920985.html
Copyright © 2020-2023  润新知