面试准备之手写Promise

本文是我在看完尚硅谷Promise教程后整理的手写Promsie,内容可能会稍许有点偏差,仅供参考。

当然,都看到手写Promise了,所以肯定对Promise的基本使用是没问题了,下面就来看看如何手写一份Promise吧。

一、搭建Promise骨架

新建lib文件夹,添加Promise.js文件。

首先采用ES5语法实现,后续会讲解ES6语法实现

// 自定义Promise函数模块: IIFE
(function (window) {
    // Promise构造函数
    // executor: 执行器函数(同步执行)
    function Promise(executor) {

    }

    // Promise原型对象的then(),指定成功和失败的回调函数,返回一个新的Promise对象
    Promise.prototype.then = function (onResolved, onRejected) {

    }

    // Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
    Promise.prototype.catch = function (onRejected) {

    }

    // Promise函数对象的resolve方法
    Promise.resolve = function (value) {

    }

    // Promise函数对象的reject方法
    Promise.reject = function (reason) {

    }

    // Promise函数对象的all方法
    Promise.all = function (promises) {

    }

    // Promise函数对象的race方法
    Promise.race = function (promises) {

    }

    // 向外暴露promise函数
    window.Promise = Promise
})(window)

二、完善构造函数

const PENDING = "pending"
const RESOLVED = "resolved"
const REJECTED = "rejected"
// Promise构造函数
// executor: 执行器函数(同步执行)
function Promise(executor) {
    const self = this
    self.status = PENDING
    self.data = undefined
    self.callbacks = []

    function resolve(value) {
        if (self.status !== PENDING) {
            return 
        }
        // 将状态改为resolved
        self.status = RESOLVED
        // 保存value数据
        self.data = value
        // 如果有待执行的callback函数,立即异步执行回调函数onResolved
        if (self.callbacks.length > 0) {
            setTimeout(() => {
                self.callbacks.forEach(callbacksObj => {
                    callbacksObj.onResolved(value)
                })
            }, 0);
        }
    }

    function reject(reason) {
        if (self.status !== PENDING) {
            return 
        }
        // 将状态改为resolved
        self.status = REJECTED
        // 保存value数据
        self.data = reason
        // 如果有待执行的callback函数,立即异步执行回调函数onRejected
        if (self.callbacks.length > 0) {
            setTimeout(() => {
                self.callbacks.forEach(callbacksObj => {
                    callbacksObj.onRejected(reason)
                })
            }, 0);
        }
    }

    // 立即同步执行executor
    try {
        executor(resolve, reject)
    } catch (error) {
        reject(error)
    }
}

三、完善then方法

Promise.prototype.then = function (onResolved, onRejected) {
        onResolved = typeof onResolved === 'function' ? onResolved : value => value
        onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}

        const self = this
        return new Promise((resolve, reject) => {
            function handle(callback) {
                try {
                    const result = callback(self.data)
                    if (result  instanceof Promise) {
                        result.then(
                            value => resolve(value),
                            reason => reject(reason)
                        )
                        // 简洁版
                        // result.then(resolve, reject)
                    } else {
                        resolve(result)
                    }
                } catch (error) {
                    reject(error)
                }
            }

            if (self.status === PENDING) {
                self.callbacks.push({
                    onResolved (value) {
                        handle(onResolved)
                    },
                    onRejected (reason) {
                        handle(onRejected)
                    }
                })
            } else if (self.status === RESOLVED) {
                setTimeout(() => {
                    handle(onResolved)
                });
            } else { // self.status = REJECTED
                setTimeout(() => {
                    handle(onRejected)
                });
            }
        })
    }

四、完善catch方法

// Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected)
}

五、完善resolve方法

// Promise函数对象的 resolve 方法
//返回一个新的Promise对象,Promise.resolve()中可以传入Promise
Promise.resolve = function (value) {
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(resolve, reject)
        } else {
            resolve(value)
        }
    })
}

六、完善reject方法

// Promise函数对象的 reject 方法
    //返回一个新的Promise对象 Promise.reject中不能再传入Promise
    Promise.reject = function (reason) {
        return new Promise((resolve, reject) => {
            reject(reason)
        })
    }

七、完善all方法

 // Promise函数对象的all方法
Promise.all = function (promises) {
    const values = new Array(promises.length)
    let successCount = 0
    return new Promise((resolve, reject) => {
        promises.forEach((p, index) => {
            Promise.resolve(p).then(
                value => {
                    successCount++
                    values[index] = value
                    if (successCount === promises.length) {
                        resolve(values)
                    } 
                },
                // 如果失败
                reason => {
                    reject(reason)
                }
            )
        })
    })
}

八、完善race方法

// Promise函数对象的race方法
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        promises.forEach(p => {
            Promise.resolve(p).then(
                value => {
                    resolve(value)
                }, reason => {
                    reject(reason)
                }
            )
        })
    })
}

总结:

  1. es5版本

    // 自定义Promise函数模块: IIFE
    (function (window) {
    
        const PENDING = 'pending'
        const RESOLVED = 'resolved'
        const REJECTED = 'rejected'
        // Promise构造函数
        // executor: 执行器函数(同步执行)
        function Promise(executor) {
            const self = this
            self.status = PENDING
            self.data = undefined
            self.callbacks = []
    
            function resolve(value) {
                if (self.status !== PENDING) {
                    return 
                }
                // 将状态改为resolved
                self.status = RESOLVED
                // 保存value数据
                self.data = value
                // 如果有待执行的callback函数,立即异步执行回调函数onResolved
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onResolved(value)
                        })
                    });
                }
            }
    
            function reject(reason) {
                if (self.status !== PENDING) {
                    return 
                }
                // 将状态改为resolved
                self.status = REJECTED
                // 保存value数据
                self.data = reason
                // 如果有待执行的callback函数,立即异步执行回调函数onRejected
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onRejected(reason)
                        })
                    });
                }
            }
    
            // 立即同步执行executor
            try {
                executor(resolve, reject)
            } catch (error) {
                reject(error)
            }
        }
    
        // Promise原型对象的then(),指定成功和失败的回调函数,返回一个新的Promise对象
        Promise.prototype.then = function (onResolved, onRejected) {
            onResolved = typeof onResolved === 'function' ? onResolved : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : reason => {throw reason}
    
            const self = this
            return new Promise((resolve, reject) => {
                function handle(callback) {
                    try {
                        const result = callback(self.data)
                        if (result  instanceof Promise) {
                            result.then(
                                value => resolve(value),
                                reason => reject(reason)
                            )
                            // 简洁版
                            // result.then(resolve, reject)
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                }
    
                if (self.status === PENDING) {
                    self.callbacks.push({
                        onResolved (value) {
                            handle(onResolved)
                        },
                        onRejected (reason) {
                            handle(onRejected)
                        }
                    })
                } else if (self.status === RESOLVED) {
                    setTimeout(() => {
                        handle(onResolved)
                    });
                } else { // self.status = REJECTED
                    setTimeout(() => {
                        handle(onRejected)
                    });
                }
            })
        }
    
        // Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
        Promise.prototype.catch = function (onRejected) {
            return this.then(undefined, onRejected)
        }
    
        // Promise函数对象的 resolve 方法
        //返回一个新的Promise对象,Promise.resolve()中可以传入Promise
        Promise.resolve = function (value) {
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(resolve, reject)
                } else {
                    resolve(value)
                }
            })
        }
    
        // Promise函数对象的 reject 方法
        //返回一个新的Promise对象 Promise.reject中不能再传入Promise
        Promise.reject = function (reason) {
            return new Promise((resolve, reject) => {
                reject(reason)
            })
        }
    
        // Promise函数对象的all方法
        Promise.all = function (promises) {
            const values = new Array(promises.length)
            let successCount = 0
            return new Promise((resolve, reject) => {
                promises.forEach((p, index) => {
                    Promise.resolve(p).then(
                        value => {
                            successCount++
                            values[index] = value
                            if (successCount === promises.length) {
                                resolve(values)
                            } 
                        },
                        // 如果失败
                        reason => {
                            reject(reason)
                        }
                    )
                })
            })
        }
    
        // Promise函数对象的race方法
        Promise.race = function (promises) {
            return new Promise((resolve, reject) => {
                promises.forEach(p => {
                    Promise.resolve(p).then(
                        value => {
                            resolve(value)
                        }, reason => {
                            reject(reason)
                        }
                    )
                })
            })
        }
    
        // 向外暴露promise函数
        window.Promise = Promise
    })(window)
    
  2. class版本

(function (window) {

    const PENDING = 'pending'
    const RESOLVED = 'resolved'
    const REJECTED = 'rejected'

    class Promise {
        constructor(executor) {
            const self = this
            self.status = PENDING
            self.data = undefined
            self.callbacks = []

            function resolve(value) {
                if (self.status !== PENDING) {
                    return
                }
                // 将状态改为resolved
                self.status = RESOLVED
                // 保存value数据
                self.data = value
                // 如果有待执行的callback函数,立即异步执行回调函数onResolved
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onResolved(value)
                        })
                    });
                }
            }

            function reject(reason) {
                if (self.status !== PENDING) {
                    return
                }
                // 将状态改为resolved
                self.status = REJECTED
                // 保存value数据
                self.data = reason
                // 如果有待执行的callback函数,立即异步执行回调函数onRejected
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onRejected(reason)
                        })
                    });
                }
            }

            // 立即同步执行executor
            try {
                executor(resolve, reject)
            } catch (error) {
                reject(error)
            }
        }

        // Promise原型对象的then(),指定成功和失败的回调函数,返回一个新的Promise对象
        then(onResolved, onRejected) {
            onResolved = typeof onResolved === 'function' ? onResolved : value => value
            onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }

            const self = this
            return new Promise((resolve, reject) => {
                function handle(callback) {
                    try {
                        const result = callback(self.data)
                        if (result instanceof Promise) {
                            result.then(
                                value => resolve(value),
                                reason => reject(reason)
                            )
                            // 简洁版
                            // result.then(resolve, reject)
                        } else {
                            resolve(result)
                        }
                    } catch (error) {
                        reject(error)
                    }
                }

                if (self.status === PENDING) {
                    self.callbacks.push({
                        onResolved(value) {
                            handle(onResolved)
                        },
                        onRejected(reason) {
                            handle(onRejected)
                        }
                    })
                } else if (self.status === RESOLVED) {
                    setTimeout(() => {
                        handle(onResolved)
                    });
                } else { // self.status = REJECTED
                    setTimeout(() => {
                        handle(onRejected)
                    });
                }
            })
        }

        // Promise原型对象的catch(),指定失败的回调函数,返回一个新的promise对象
        catch(onRejected) {
            return this.then(undefined, onRejected)
        }

        // Promise函数对象的 resolve 方法
        //返回一个新的Promise对象,Promise.resolve()中可以传入Promise
        static resolve = function (value) {
            return new Promise((resolve, reject) => {
                if (value instanceof Promise) {
                    value.then(resolve, reject)
                } else {
                    resolve(value)
                }
            })
        }

        // Promise函数对象的 reject 方法
        //返回一个新的Promise对象 Promise.reject中不能再传入Promise
        static reject = function (reason) {
            return new Promise((resolve, reject) => {
                reject(reason)
            })
        }

        // Promise函数对象的all方法
        static all = function (promises) {
            const values = new Array(promises.length)
            let successCount = 0
            return new Promise((resolve, reject) => {
                promises.forEach((p, index) => {
                    Promise.resolve(p).then(
                        value => {
                            successCount++
                            values[index] = value
                            if (successCount === promises.length) {
                                resolve(values)
                            }
                        },
                        // 如果失败
                        reason => {
                            reject(reason)
                        }
                    )
                })
            })
        }

        // Promise函数对象的race方法
        static race = function (promises) {
            return new Promise((resolve, reject) => {
                promises.forEach(p => {
                    Promise.resolve(p).then(
                        value => {
                            resolve(value)
                        }, reason => {
                            reject(reason)
                        }
                    )
                })
            })
        }
    }
    // 向外暴露promise函数
    window.Promise = Promise
})(window)
  • 4
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值