Promise动态方法及静态方法实现

1,493 阅读2分钟

接上篇 符合promiseA+的抄袭 的实现,promise 还有一些在规范之外的语法糖实现

catch finally resolve reject race all

实现代码

catch

MyPromise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected)
}

测试代码

new MyPromise((resolve, reject) => {
    reject('err')
}).catch((reason) => {
    console.log(reason) // err

    return 'data'
}).then((value) => {
    console.log(value) // data
})

resolve

MyPromise.resolve = (data) => {
    // 如果data是个promise会直接返回
    if (data instanceof MyPromise) {
        return data
    } else {
        return new MyPromise(resolve => {
            resolve(data)
        })
    }
}

测试代码

MyPromise.resolve(2).then((data) => {
    console.log(data) // 2
})

MyPromise.resolve(
    new MyPromise((resolve, reject) => {
        reject(5)
    })
).catch((data) => {
    console.log(data) // 5
})

reject

// 和Promise.resolve不同,会直接reject
MyPromise.reject = (reason) => {
    return new MyPromise((resolve, reject) => {
        reject(reason)
    })
}

测试代码

MyPromise.reject(2).catch((reason) => {
    console.log(reason) // 2
})

finally

MyPromise.prototype.finally = function (callback) {
    return this.then((value) => {
        // callback没有参数、
        // 如果callback返回的是promise,则会等待promise执行
        return MyPromise.resolve(callback()).then(() => {
            // finally会保持promise状态和值
            return value
        })
    }, (reason) => {
        return MyPromise.resolve(callback()).then(() => {
            // finally会保持promise状态和值
            throw reason
        })
    })
}

测试代码

MyPromise.resolve(2).finally((value) => {
    console.log(value) // undefined
}).then((value) => {
    console.log(value) // 2
})

MyPromise.reject(2).finally((reason) => {
    console.log(reason) // undefined
}).catch((reason) => {
    console.log(reason) // 2
})

MyPromise.resolve(2).finally((value) => {
    return new MyPromise((resolve) => {
        setTimeout(() => {
            resolve(100)
        }, 1000)
    })
}).then((value) => {
    console.log(value) // 100
})

all

MyPromise.all = (paramList) => {
    const len = paramList.length
    const result = []
    let count = 0

    return new MyPromise((resolve, reject) => {
        // 参数长度为0直接resolve
        if (len === 0) resolve(result)

        paramList.forEach((param, index) => {
            // 如果数组元素不是promise也会包装成promise
            MyPromise.resolve(param).then((value) => {
                count++
                result[index] = value

                if (count === len) {
                    resolve(result)
                }
            }, (reason) => {
                reject(reason)
            })
        })
    })
}

测试代码

const p1 = new MyPromise((resolve) => {
    setTimeout(() => {
        resolve(3)
    }, 2000)
})

const p2 = new MyPromise((resolve) => {
    setTimeout(() => {
        resolve(4)
    }, 1000)
})

const p3 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject(5)
    }, 1000)
})


MyPromise.all([
    1, 2, p1, p2
]).then((value) => {
    console.log(value) // [1, 2, 3, 4]
})

MyPromise.all([
    1, 2, p1, p2, p3
]).catch((reason) => {
    console.log(reason) // 5
})

MyPromise.all([]).then((value) => {
    console.log(value) // []
})

race

MyPromise.race = (paramList) => {
    return new MyPromise((resolve, reject) => {
        // 空数组则保持等待状态
        if (paramList.length === 0) return

        paramList.forEach((param) => {
            Promise.resolve(param).then((value) => {
                resolve(value)
            }, (reason) => {
                reject(reason)
            })
        })
    })
}

测试代码

const p1 = new MyPromise((resolve) => {
    setTimeout(() => {
        resolve(1)
    }, 1000)
})

const p2 = new MyPromise((resolve) => {
    setTimeout(() => {
        resolve(2)
    }, 2000)
})

const p3 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        reject(3)
    }, 500)
})

MyPromise.race([]).then(value => {
    console.log(value)
}, reason => {
    console.log(reason)
})

MyPromise.race([1, 2]).then(value => {
    console.log(value) // 1
}, reason => {
    console.log(reason)
})

MyPromise.race([p1, 4]).then(value => {
    console.log(value) // 4
}, reason => {
    console.log(reason)
})

MyPromise.race([p1, p2]).then(value => {
    console.log(value) // 1
}, reason => {
    console.log(reason)
})

MyPromise.race([p1, p3]).then(value => {
    console.log(value)
}, reason => {
    console.log(reason) // 3
})

参考


欢迎到前端学习打卡群一起学习~516913974