obsidian-computer
前端识记

手写Promise

Promise的用法就是 1. new 中传入这个任务,然后定义什么叫成功,什么叫失败 2. 成功/失败后的后续操作 ## 思路 1. 写出构造器

最后更新 2026年8月20日

Promise的用法就是

  1. new 中传入这个任务,然后定义什么叫成功,什么叫失败
  2. 成功/失败后的后续操作

思路

  1. 写出构造器

  2. 搞定then方法

构造器

class MyPromise {
    /**
     * 
     * @param {*} executor 执行器任务函数(立即执行)
     */
    constructor(executor) {
        // 数据结果
        const resolve = (data) => { };
        // 报错原因
        const reject = (error) => { };
        executor(resolve, reject);
    }
}

const p = new Promise((resolve, rejeect) => {
    let data = 1;
    resolve(data);
})

设置状态、结果给到对象中:

class MyPromise {
    #status = 'pending';
    #result = undefined;


    /**
     * 
     * @param {*} executor 执行器任务函数(立即执行)
     */
    constructor(executor) {
        // 数据结果
        const resolve = (data) => {
            if (this.#status != 'pending') return
            this.#status = 'fulfilled';
            this.#result = data
        };
        // 报错原因
        const reject = (error) => {
            if (this.#status != 'pending') return

            this.#status = 'rejected'
            this.#result = error
        };
        executor(resolve, reject);
    }
}

const p = new Promise((resolve, reject) => {
    let data = 1;
    resolve(data);
    reject(data)
})

可以抽离函数、设置常量; 注意异常处理,如果抛出了异常,最好可以reject调用抛出错误

       try {
            executor(resolve, reject);
        } catch (e) {
            reject(e)
        }

手写then方法

/**
** 成功、失败后调用方法
*/
promise.then((onFulfilled,onRejected)=>{})
  1. 回调什么时候调用
  2. 返回Promise的新状态是什么

Promise已决才会选择成功/失败的函数回调。所以在调用then的时候可能不会立即实行,要等到合适的时候,无法执行怎么办,那就给他加到队列里。

  // #settleedHandlers = []; // 已决后的后续处理,使用数组是因为可能p.then().then()
    then(onFulfilled, onRejected) {
        const prom = new MyPromise(() => { })
        this.#settleedHandlers.push({
            onFulfilled, onRejected,prom // 后续还需要处理这个promise状态
        })
        // 什么时候处理这个回调?

        return prom;
    }

我们举一个测试用例先:

const p = new MyPromise((resolve) => {
    setTimeout(() => {
        resolve(5)
    }, 1000);
})

p.then(console.log)

很明显,他先 then注册方法(这个时候已经加了#settledhandlers),然后调用resolve方法的 所以在resolve的时候就已经有这些信息了,所以第一个处理的节点是处理状态变化过后

反向链接(1)

评论

关系图谱

工程化与性能优化网络React快速总结This指向TypeScript 快速上手Web components00-总览与阅读路线01-reactivity-effect与依赖收集02-reactivity-reactive-ref-computed03-runtime-挂载流程04-runtime-组件系统05-runtime-更新与diff06-compiler-三段式07-方法论-如何啃大型开源项目README前端小记01-js-core02-browser03-network04-css-html05-react06-vue07-engineering08-scenarios09-handwritten-js10-algorithms11-ai-frontend手写Promise踩坑记录前端识记AI总结mini-vue-reading前端面试

On this page