手写Promise.all

176 阅读1分钟

💁🏼‍♀️Promised手写常见,但是很费时间,有时候写出promise能写一个小时。所以Promise.all的实现思想和手写能力最常考查,我们应该做到了熟于心。

面试官问: 你知道Promise.all吗?

你可能回答:Promise.all接收一个数组,数组里面都是promise。

这时候,面试官反问:数组里面真的都是promise吗?

面对面试官的质疑,你可能会反应过来:里面也不全都是promise,也可以是常量。



面试官问: 它的执行情况是怎么回事呢?

你的回答:等到里面的promise全部执行完成后,才会返回结果。

面试官问: 如果里面有一个执行失败了呢?

你的回答:它会在catch里面捕获。

面试官又问:那其他的还会执行吗?

这时候你可能不会了。 答案是:会的,因为promise在实例化时,就执行了;.then()只是用来看它的结果。


💁🏼‍♀️Promise.all手写版

 function myPromiseAll(_promises){
            // Promise中传入的不一定是数组。是具有迭代器的属性,迭代器所有的Promise都resolve后组成为数组
            return new Promise((resolve,reject)=>{
                const promises = Array.from(_promises);
                // 并发执行promise,记住每个promise的位置
                const result = [];
                const len = promises.length;
                let count = 0;
                for(let i =0;i<len ;i++){
                    // 注意有的数组项有可能不是Promise,需要手动转化一下
                    Promise.resolve(promises[i]).then( o=>{
                        // 收集每个Promise的返回值
                        result[i] = o;
                        // 当所有的Promise都成功了,那么将返回的Promise结果设置为result
                        if(++count === len){
                            resolve(result);
                        }
                        // 监听数组项中的Promise catch只要有一个失败,那么我们自己返回的Promise也会失败
                    }).catch(e=>reject(e))
                }
            })
        }
        myPromiseAll([1,2,3]).then(o => console.log(o));
        myPromiseAll([1,Promise.resolve(3)]).then(o=>console.log(o));
        myPromiseAll([1,Promise.reject(3)]).then(o=>console.log('done')).catch(e=>console.log(e));

截屏2022-04-27 上午10.35.48.png