【前端面试题】手写一个Promise.all方法(推荐收藏)

【前端面试题】Promise的使用(异步编程、回调地狱)icon-default.png?t=LA92https://blog.csdn.net/weixin_46318413/article/details/122027650是什么?

Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。

MDN_Promise.all()https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/allhttps://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

情形一:所有输入的promise的resolve回调都结束,才能输出promise.all的回调

//定义p1是在1秒后执行结果为{name: 'dai'}的promise的对象
let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve({
            name: 'dai'
        });
    }, 1000);
})
//定义p2是在2秒后执行结果为222的promise的对象
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(222);
    }, 2000);
})
//Promise.all() 方法接收一个promise的iterable类型,判断传入的每一个对象是否都成功并返回一个数组,否则会报错
//因为要等两个promise全部执行完才进行输出,由于p2需要两秒后执行,所以会在两秒后将两个执行结果一起输出
Promise.all([p1, p2]).then(res => {
    console.log(res);//输出为[{name:'dai'},222]
})

情形二:只要任何一个输入的promise的reject回调执行,就会立即抛出错误,并且reject的是第一个抛出的错误信息

//定义p1是在1秒后执行结果为{name: 'dai'}的promise的对象
let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(111);
    }, 1000);
})
//定义p2是在2秒后执行结果为222的promise的对象
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        reject(222);
    }, 2000);
})

Promise.all([p1, p2]).then((res) => {
    console.log(res)//报错输出111
})

如何手写Promise.all函数?

//定义p1是在1秒后执行结果为{name: 'dai'}的promise的对象
let p1 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve({
            name: 'dai'
        });
    }, 1000);
})
//定义p2是在2秒后执行结果为222的promise的对象
let p2 = new Promise((resolve, reject) => {
    setTimeout(() => {
        resolve(222);
    }, 2000);
})

//手写一个promise.all
function myPromiseAll(lists) {
    return new Promise((resolve, reject) => {
        let resArr = [];//定义执行结果
        let n = 0;//判断是否全部
        lists.forEach(list => {
            list.then(item => {
                //把输入数组中的每一个promise的执行结果push到resArr中
                resArr.push(item);
                n++;
                //通过n判断是否执行结束
                if (n === lists.length) {
                    return resolve(resArr)
                }
            }, (reason) => {
                //如果遇到有一个reject,立马结束并输出第一个reject
                return reject(reason);
            })
        });
    })
}

//因为返回的是Promise对象,所以要通过then拿到执行结果
myPromiseAll([p1, p2]).then(res => {
    console.log(res)//输出[{name:'dai'},222]
})

以上就是Promise.all的机制以及手写方法。

我是前端Dai,一个会将自己平时项目中常见的问题以及笔试面试的知识在CSDN与大家分享的coder,希望大家一起进步,加油。

猜你喜欢

转载自blog.csdn.net/weixin_46318413/article/details/122023908#comments_20499161
今日推荐