SOURCE

function promiseAll(promises) {
    return new Promise(function (resolve, reject) {
        if (!Array.isArray(promises)) {
            return reject(new TypeError("argument must be anarray"))
        }
        var countNum = 0;
        var promiseNum = promises.length;
        var resolvedvalue = new Array(promiseNum);
        for (var i = 0; i < promiseNum; i++) {
            (function (i) {
                // Promise.resolve包裹一层的原因是:
                // 数组中不一定需要都是Promise对象,但是一定具有Iterator接口,
                // 如果不是的话,就会调用Promise.resolve将其转化为Promise对象之后再进行处理。
                Promise.resolve(promises[i]).then(function (value) {
                    countNum++;
                    resolvedvalue[i] = value;
                    if (countNum === promiseNum) {
                       resolve(resolvedvalue)
                    }
                }, function (reason) {
                    reject(reason)
                })
            })(i)
        }
    })
}
var p1 = Promise.resolve(1),
    p2 = Promise.resolve(2),
    p3 = Promise.resolve(3);
promiseAll([p1, p2, p3]).then(function (value) {
    console.log(value)
})

// Promise.finally实现
Promise.prototype.finally = function(callback) {
    return this.then(value => {
        Promise.resolve(callback()).then(() => value)
    }, error => {
        Promise.resolve(callback()).then(() => {throw error})
    })
}
console 命令行工具 X clear

                    
>
console