JavaScript面试核心:Promise手写实现详解

作者:异步漫步

时间:2026-10-26

浏览:506

本文深入解析JavaScript中Promise的手写实现,涵盖从基础构造函数到then、catch链式调用的完整逻辑。通过剖析状态机流转、微任务调度及错误捕获机制,帮助开发者透彻理解Promise内部原理,从容应对技术面试中的源码级考察。

文章目录

Promise手写

在JavaScript技术面试中,Promise相关题目属于高频考点,其中要求候选人手写实现Promise更是面试官的常规提问。因此,深入理解并掌握Promise的内部机制与实现细节至关重要。

框架

(function(window) {
    
    MyPromise.prototype.then = function (onResolved, onRejected) {}
    MyPromise.prototype.catch = function (onRejected) {}
    
    function MyPromise(executor){

        function resolve(value){}

        function reject(error){}

        try{
            executor(resolve, reject)
        }catch(error){
            reject(error)
        }
    }

    window.MyPromise = MyPromise
}(window))

完整代码

    (function (window) {
        //将.then,.catch方法挂载在MyPromise原型上
        MyPromise.prototype.then = function (onResolved, onRejected) {//.then接受两个回调函数,resolved状态和rejeced状态

            // .then返回一个promise对象
            return new MyPromise((resolve, reject) => {
                let self = this;

                if (self.status === 'pending') {//如果MyPromise状态为pending,将两个回调函数push进回调数组中等待

                    this.callbacks.push({ onResolved, onRejected })

                } else if (self.status === 'resolved') {  //如果MyPromise状态为resolved,将onResolved直接调用
                    setTimeout(() => {
                        //检查.then中的回调有没有return返回值
                        const result = onResolved(self.data)

                        //如果没有return返回值,默认返回promise对象
                        if (result instanceof MyPromise) {
                            result.then((res => resolve(res), err => reject(err)))
                            return result
                        } else {
                            resolve(result)
                        }
                    })
                } else {

                    setTimeout(() => {
                        onResolved(self.data)
                    })
                }
            })

        }
        MyPromise.prototype.catch = function (onRejected) { //.catch接受一个回调函数

            if (this.status === 'pending') {
                // 将回调函数放入callbacks数组中
                this.callbacks.push({ onRejected })
            } else if (this.status === 'rejected') {
                setTimeout(() => {
                    onRejected(this.data)
                })

            }
        }

        // MyPromise构造函数接受一个执行函数
        function MyPromise(executor) {
            const self = this;
            self.data = undefined;
            self.callbacks = []
            //设置promise对象初始状态为pending
            self.status = 'pending'
            //执行函数第一个参数为resolve回调
            function resolve(value) {
                //如果状态不是pending,则直接返回
                if (self.status !== 'pending') {
                    return
                }

                // 执行resolve,promise对象状态变更
                self.status = 'resolved';

                // 拿到resolve中的值
                self.data = value;

                // 调用callbacks中的回调函数
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onResolved(value)
                        });
                    })
                }
            }

            // 执行函数第二个参数为rejecr回调
            function reject(error) {
                //如果状态不是pending,则直接返回
                if (self.status !== 'pending') {
                    return
                }

                // 执行resolve,promise对象状态变更
                self.status = 'rejected';

                // 拿到resolve中的值
                self.data = error;

                // 调用callbacks中的回调函数
                if (self.callbacks.length > 0) {
                    setTimeout(() => {
                        self.callbacks.forEach(callbacksObj => {
                            callbacksObj.onRejected(value)
                        });
                    })
                }
            }
            //使用try catch捕获错误
            try {
                // 在try内执行执行函数
                executor(resolve, reject)
            } catch (error) {
                // 如果出错,默认执行reject
                reject(error);
            }

        }

        window.MyPromise = MyPromise
    }(window))

测试

resolve

    let MyPromiseTest = new MyPromise((resolve, reject) => {
        resolve('resolve')
    })
    MyPromiseTest.then(res => {
        console.log(res);
    })
    
    //   resolve
    let MyPromiseTest = new MyPromise((resolve, reject) => {
        resolve('resolve');
    })
    MyPromiseTest.then(res => {
        console.log(res);

    })
        .then(res => {
            console.log('我是.then()后面的.then()');
        })
        
    //   resolve
    //   我是.then()后面的.then()

reject

    let MyPromiseTest = new MyPromise((resolve, reject) => {
        reject('reject')
    })
    MyPromiseTest.catch(err => {
        console.log(err);
    })
    
    //   reject
    let MyPromiseTest = new MyPromise((resolve, reject) => {
        console.log(a);
    })
    MyPromiseTest.catch(err => {
        console.log('捕获错误' + ':' + err);
    })
    
    //   捕获错误:ReferenceError: a is not defined

至此,关于JavaScript面试中Promise手写实现的介绍已告一段落。如需了解更多相关技术内容,建议查阅本站往期文章或继续浏览后续章节,感谢大家的支持。

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章