# Promise 进阶

# Promise.resolve

这里就不考虑参数是thenable对象了,那么参数有两种情况:

  1. Promise 实例,直接返回
  2. 不是 Promise 实例,返回一个新的 Promise 对象,状态为FULFILLED
Promise.resolve = function(param){
    if (param instanceof MyPromise) {
        return param
    }
    return new MyPromise((resolve, reject) => resolve(param))
}

# Promise.reject

Promise.reject 中传入的参数会作为一个 reason 原封不动地往下传, 实现如下:

Promise.reject = function(param){
    return new MyPromise((resolve, reject) => reject(param))
}

# Promise.finally

无论当前 Promise 是成功还是失败,调用 finally 之后都会执行 finally 中传入的函数,并且将值原封不动的往下传。

Promise.finally = function(callback) {
    this.then(value => {
        return Promise.resolve(callback()).then(() => {
            return value;
        })
    }, error => {
        return Promise.resolve(callback()).then(() => {
            throw error;
        })
    })
}

# Promise.all

返回一个 promise 对象,只有当所有 promise 都成功时返回的 promise 状态才成功,需要注意的点是:

  1. 数组成员不为promise,则直接进行resolve()
  2. 所有的 promise 状态变为 FULFILLED,返回的 promise 状态才变为 FULFILLED
  3. 一个 promise 状态变为REJECTED,返回的 promise 状态就变为REJECTED
  4. 在任何情况下,Promise.all 返回的 promise 的完成状态的结果都是一个数组

具体实现如下:

Promise.all = function(promises){
    return new MyPromise((resolve, reject) => {
        let result = [];
        let len = promises.length;
        
        if (len === 0) {
            return resolve(result)
        }

        for (let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then(res => {
                result[i] = res
                if (i == len - 1) { // 最后一个
                    resolve(result)
                }
            }).catch(err => {
                reject(err)
            })
        }
    })
}

# Promise.race

race 的实现相比之下就简单一些,只要有一个 promise 执行完,直接 resolve 并停止执行。

Promise.race = function(promises){
    return new MyPromise((resolve, reject) => {
        let len = promises.length;
        if (len === 0) return
        for (let i = 0; i < len; i++) {
            Promise.resolve(promises[i]).then(res => {
                resolve(res)
                return
            }).catch(err => {
                reject(err)
                return
            })
        }
    })
}

到此为止,一个完整的 Promise 就被我们实现完啦。从原理到细节,我们一步步拆解和实现,希望大家在知道 Promise 设计上的几大亮点之后,也能自己手动实现一个 Promise,让自己的思维层次和动手能力更上一层楼!

# Promise实现网络超时判断

使用Promise实现网络请求超时判断,超过三秒视为超时。 借助的是Promise.race这个方法:

const uploadFile = () => {
    return Promise.race([
        uploadFilePromise(),
        uploadFileTimeout(3000)
    ])
}

function uploadFilePromise() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve('OK')
        }, 3100)
    })
}

function uploadFileTimeout() {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            reject('Time out ~~')
        }, 3000)
    })
}

uploadFile().then((res) => {
    console.log(res)
}).catch((err) => {
    console.log(err)
})