手写实现 Promise/A+ 标准

简介: 手写实现 Promise/A+ 标准

前言


本文仅作为个人记录,文中可能存在不严谨的地方。


要了解更多可以看下这两篇文章:

史上最易读懂的 Promise/A+ 完全实现

promise/A+规范翻译以及手写实现


正文


Promise/A+ 的标准有哪些?

  1. 只有一个 then 方法,没有 catch、race、all 等方法。
  2. then 返回一个新的 Promise。
  3. 不同的 Promise 的实现需要相互调用。
  4. Promise 的状态有 pending、fullfilled、rejected 三种。初始状态是 pending ,可以由 pending 转化为 fullfilled 或者 rejected。一旦状态确定之后,不能再被改变。
  5. 更具体的官方标准,看这里


下面上代码

function MyPromise(executor) {
    const _this = this;
    // 状态
    _this.status = 'pending';
    // resolve 值
    _this.value = null;
    // reject 原因
    _this.reason = null;
    // resolve、reject 函数
    _this.onFullfilled = [];
    _this.onRejected = [];
    function resolve(value) {
        if (value instanceof MyPromise) {
            return value.then(resolve, reject);
        }
        // 其实这里采用 setTimeout 方式实现异步执行 onFullfilled/onRejected 不太符合 Event Loop 机制。下面 reject 同理。
        setTimeout(() => {
            // 只有状态为 pending 才能被改变
            if (_this.status == 'pending') {
                _this.value = value;
                _this.status = 'resolved';
                _this.onFullfilled.forEach(currentValue => currentValue(value));
            }
        }, 0);
    }
    function reject(reason) {
        setTimeout(() => {
            // 只有状态为 pending 才能被改变
            if (_this.status == 'pending') {
                _this.reason = reason;
                _this.status = 'rejected';
                _this.onRejected.forEach(currentValue => currentValue(reason));
            }
        }, 0);
    }
    // 注意:若执行过程出现异常,则捕获异常并执行 reject 函数。
    try {
        executor(resolve, reject)
    } catch (e) {
        reject(e);
    }
}
function resolvePromise(promise2, x, resolve, reject) {
    let then;
    let thenCallorThrow = false;
    if (promise2 === x) {
        return reject(new TypeError('same Promise!'))
    }
    if (x instanceof MyPromise) {
        if (x.status === 'pending') {
            x.then(value => {
                resolvePromise(promise2, value, resolve, reject)
            }, reject)
        } else {
            x.then(resolve, reject)
        }
        return
    }
    if ((x !== null) && ((typeof x === 'object') || (typeof x === 'function'))) {
        try {
            then = x.then;
            if (typeof then === 'function') {
                then.call(x, res => {
                    if (thenCallorThrow) return;
                    thenCallorThrow = true;
                    return resolvePromise(promise2, res, resolve, reject);
                }, err => {
                    if (thenCallorThrow) return;
                    thenCallorThrow = true;
                    return reject(err)
                })
            } else {
                resolve(x);
            }
        } catch (e) {
            if (thenCallorThrow) return;
            thenCallorThrow = true;
            return reject(e)
        }
    } else {
        return resolve(x)
    }
}
MyPromise.prototype.then = function (onFullfilled, onRejected) {
    const _this = this;
    let promise2;   // promise.then() 返回一个 promise 对象
    // Promise 值的穿透处理:
    // 场景如: new Promise(resolve => resolve('abc')).then().catch().then(res => {console.log('print abc')})
    onFullfilled = typeof onFullfilled === 'function' ? onFullfilled : val => val;
    onRejected = typeof onRejected === 'function' ? onRejected : err => { throw err };
    switch (_this.status) {
        case 'pending':
            promise2 = new MyPromise((resolve, reject) => {
                _this.onFullfilled.push(value => {
                    try {
                        let x = onFullfilled(value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                });
                _this.onRejected.push(reason => {
                    try {
                        let x = onRejected(reason);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                });
            })
        case 'resolved':
            promise2 = new MyPromise((resolve, reject) => {
                setTimeout(() => {
                    try {
                        let x = onFullfilled(_this.value);
                        resolvePromise(promise2, x, resolve, reject);
                    } catch (e) {
                        reject(e)
                    }
                });
            })
        case 'rejected':
            promise2 = new MyPromise((resolve, reject) => {
                setTimeout(() => {
                    try {
                        let x = onRejected(_this.reason);
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (e) {
                        reject(e)
                    }
                });
            })
        default:
            break;
    }
    return promise2;
}
// Promise 标准里面没有 catch、race、all 等方法,只有一个 then 方法
MyPromise.prototype.catch = function (onRejected) {
    return this.then(null, onRejected)
}
new MyPromise((resolve, reject) => {
    resolve('right');
}).then(res => {
    console.log(res)
}, err => {
    console.warn(err)
})


目录
相关文章
|
6天前
|
存储 弹性计算 人工智能
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
2025年9月24日,阿里云弹性计算团队多位产品、技术专家及服务器团队技术专家共同在【2025云栖大会】现场带来了《通用计算产品发布与行业实践》的专场论坛,本论坛聚焦弹性计算多款通用算力产品发布。同时,ECS云服务器安全能力、资源售卖模式、计算AI助手等用户体验关键环节也宣布升级,让用云更简单、更智能。海尔三翼鸟云服务负责人刘建锋先生作为特邀嘉宾,莅临现场分享了关于阿里云ECS g9i推动AIoT平台的场景落地实践。
【2025云栖精华内容】 打造持续领先,全球覆盖的澎湃算力底座——通用计算产品发布与行业实践专场回顾
|
5天前
|
云安全 人工智能 自然语言处理
阿里云x硅基流动:AI安全护栏助力构建可信模型生态
阿里云AI安全护栏:大模型的“智能过滤系统”。
|
5天前
|
人工智能 自然语言处理 自动驾驶
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
关于举办首届全国大学生“启真问智”人工智能模型&智能体大赛决赛的通知
|
Linux 虚拟化 iOS开发
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
VMware Workstation Pro 25H2 for Windows & Linux - 领先的免费桌面虚拟化软件
1080 4
|
8天前
|
存储 机器学习/深度学习 人工智能
大模型微调技术:LoRA原理与实践
本文深入解析大语言模型微调中的关键技术——低秩自适应(LoRA)。通过分析全参数微调的计算瓶颈,详细阐述LoRA的数学原理、实现机制和优势特点。文章包含完整的PyTorch实现代码、性能对比实验以及实际应用场景,为开发者提供高效微调大模型的实践指南。
677 2
|
6天前
|
编解码 自然语言处理 文字识别
Qwen3-VL再添丁!4B/8B Dense模型开源,更轻量,仍强大
凌晨,Qwen3-VL系列再添新成员——Dense架构的Qwen3-VL-8B、Qwen3-VL-4B 模型,本地部署友好,并完整保留了Qwen3-VL的全部表现,评测指标表现优秀。
508 7
Qwen3-VL再添丁!4B/8B Dense模型开源,更轻量,仍强大
|
7天前
|
JavaScript API 开发工具
如何在原生App中调用Uniapp的原生功能?
如何在原生App中调用Uniapp的原生功能?
331 139