手写Promise

本文详细解析了JavaScript中的Promise构造函数及其原型方法then和catch。通过源码分析,展示了Promise如何处理异步操作的状态变化,以及如何通过链式调用来处理成功和失败的回调。同时,介绍了Promise.resolve和Promise.reject的用法,以及Promise.all和Promise.race的实现,帮助读者全面掌握Promise的使用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

// An highlighted block
function Promise(executor) {
    /*
        Promise: 构造函数
        excutor: 执行器函数(同步回调函数)
    */
    this.status = 'preding' // 给promise对象指定status属性,初始值为prending
    this.data = undefined //给promise对象指定一个用于存储结果数据的属性
    const self = this // 保存实例对象的this的值
    this.callbacks = []// 每一个元素的结构:{onResolved(){},onRejected() {}}
    // Promise实例对象的resolve
    // 返回一个指定成功的promise
    function resolve(value) {
        // 如果当前状态不是Prending,直接结束
        if (self.status != 'preding') {
            return
        }
        //改变状态
        self.status = 'resolved'
        //保存异步操作得到的value数据
        self.data = value
        // 执行onResolve回调函数
        setTimeout(() => {
            self.callbacks.forEach(item => {
                item.onResolved(value)
            })
        })
    }
    // Promise实例对象的reject
    // 返回一个指定失败的promise
    function reject(reason) {
        // 如果当前状态不是Prending,直接结束
        if (self.status != 'preding') {
            return
        }
        //改变状态
        self.status = 'rejected'
        //保存value数据
        self.data = reason
        // 执行onRejected回调函数
        setTimeout(() => {
            self.callbacks.forEach(item => {

                item.onRejected(reason)
            })
        })
    }

    // 执行回调函数
    try {
        // 同步调用 [执行器函数]
        executor(resolve, reject)
    } catch (error) {
        // 修改promise对象状态为失败
        return reject(error)
    }
}


// Promise原型对象的then()
// 指定成功和失败的回调函数
// 返回一个新的Promise对象
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this
    // 判断回调函数参数
    if (typeof onRejected != 'function') {
        onRejected = reason => {
            throw reason;
        }
    } // 考虑异常穿透,没有指定reject,初始化reject为异常
    if (typeof onResolved != 'function') {
        onResolved = value => value
    } // 默认省略resolve,reject回调,初始化resolve,then也可以继续往下传
    return new Promise((resolve, reject) => {
        // 封装函数
        function callBack(onFun) {
            try {
                // 获取回调函数执行结果 
                let result = onFun(self.data)
                //判断 结果是否是Promise对象
                if (result instanceof Promise) {
                    result.then(v => {
                        resolve(v)
                    }, r => {
                        reject(r)
                    })
                } else {//不是直接成功
                    //状态为成功
                    resolve(result)
                }
            } catch (error) {
                reject(error)
            }
        }
        // 调用回调函数 
        if (this.status === 'resolved') {
            setTimeout(() => {
                callBack(onResolved)
            })
        }
        if (this.status === 'rejected') {
            setTimeout(() => {
                callBack(onRejected)
            })
        }
        // 改变状态前,绑定回调函数
        if (this.status === 'preding') {
            // 保存回调函数
            this.callbacks.push({
                onResolved: () => callBack(onResolved),
                onRejected: () => callBack(onRejected)
            })
        }
    })
}
// // Promise原型对象的catch()
// // 指定失败的回调函数
// // 返回一个新的Promise对象 
Promise.prototype.catch = function (onRejected) {
    return this.then(undefined, onRejected)
}

// Promise函数对象的resolve
// 返回一个指定成功的promise
Promise.resolve = function (value) {
    //返回一个promise对象
    return new Promise((resolve, reject) => {
        if (value instanceof Promise) {
            value.then(v => {
                resolve(v)
            }), r => {
                reject(r)
            }
        } else {
            resolve(value)
        }
    })
}

// Promise函数对象的reject
// 返回一个指定失败的promise
Promise.reject = function (reason) {
    return new Promise((resolve, reject) => {
        reject(reason)
    })
}

// Promise函数对象all (成功返回promise数组,数组的返回值严格对应输入的顺序)
// 返回一个promise,只有当所有promise都成功菜成功,否则只要一个失败就是失败
Promise.all = function (promises) {
    //返回结果为promise对象
    return new Promise((resolve, reject) => {
        // 声明变量
        let count = 0
        let arr = []
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                // 得知对象的状态是成功
                // 每个promise对象 都成功才修改返回Promise的状态
                count++
                arr[i] = v
                if (count == promises.length) {
                    resolve(arr)
                }
            }, r => {
                // 有一个失败就修改Promise的状态
                reject(r)
            })
        }
    })
}

// Promise函数对象race
// 返回一个promise,其结果由第一个完成的promise决定
Promise.race = function (promises) {
    return new Promise((resolve, reject) => {
        for (let i = 0; i < promises.length; i++) {
            promises[i].then(v => {
                resolve(v)
            }, r => {
                reject(r)
            }
            )
        }
    })
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值