普歌-自定义promise

Promise概念

new Promise(function () {
    
})

当传递给 new Promise 的函数被称为 executor, new Promise 被创建,executor 会被自动运行。它会提供两个参数 resolve、reject。

当 executor 获取到了结果,无论是什么时候获取到了,它都应该执行这两个回调函数。

  1. resolve 成功的回调
  2. reject 失败的回调

new Promise 构造器返回的 promise 对象具有以下的内部属性。

  1. 状态最初为 pending, 然后 resolve 被改变为 fulfilled. 在 reject 变为 rejected
  2. result 最初为 undefined, 然后 resolve(value) 改为 value, 或者在 reject(error) 变为 error.

注意: 只能改变一次,改变之后就不能够改变了。

实现 Promise

1. Promise 的基本状态, status 状态。 data 保存结果。callbacks 来存放回调。

function Promise(executor) {
    this.status = 'pending';
    this.data = null;
    this.callbacks = [];

    executor();
}

2. resolve, reject 函数. 注意:promise 的状态只能改变一次。

function Promise(executor) {
    const self = this;
    this.status = 'pending';
    this.data = null;
    this.callbacks = [];

    function resolve(value) {
        if (self.status !== 'pending') return;
        self.status = 'resolved';
        self.data = value;
    }
    function reject(reason) {
        if (self.status !== 'pending') return;
        self.status = 'rejected';
        self.data = reason;
    }
    executor(resolve, reject);
}

3. throw xxx 状态也会变为失败。

function Promise(executor) {
    const self = this;
    this.status = 'pending';
    this.data = null;
    this.callbacks = [];

    function resolve(value) {
        if (self.status !== 'pending') return;
        self.status = 'resolved';
        self.data = value;
    }
    function reject(reason) {
        if (self.status !== 'pending') return;
        self.status = 'rejected';
        self.data = reason;
    }
    try {
        executor(resolve, reject);  // 接收到 throw 之后
    } catch (error) {
        reject(error);
    }
}

4. then

Promise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    if (self.status === 'pending') {
        self.callbacks.push({
            onResolved,
            onRejected
        })
    } else if (self.status === 'resolved') {
        setTimeout(() => {
            onResolved(self.data);
        });
    } else if (self.status === 'rejected') {
        setTimeout(() => {
            onRejected(self.data);
        })
    }
}
  1. then 返回 promise then 返回一个 promise, 链式调用 then,下一次的 then 回调用来接收上一次的 then 返回的 promise 的结果。
  2. 返回的 promise 成功, 那么下一次的 then 的结果就是成功。
  3. 返回的 promise 失败,下一次的 then 的结果就是失败。
  4. 如果 返回的结果是 promise, 那么这个 promise 的结果就是当前 promise 结果。
Promise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    return new Promise((resolve, reject) => {
        if (self.status === 'pending') {
            self.callbacks.push({
                onResolved,
                onRejected
            })
        } else if (self.status === 'resolved') {
            setTimeout(() => {
                try {
                    const result = onResolved(self.data);
                    if (result instanceof Promise) {
                        result.then(
                            value => resolve(value),
                            reason => reject(reason)
                        )
                    } else {
                        resolve(result);
                    }
                } catch (error) {
                    reject(error);
                }
            });
        } else if (self.status === 'rejected') {
            setTimeout(() => {
                onRejected(self.data);
            })
        }
    })
}

5. then 返回 promise (2)

Promise.prototype.then = function (onResolved, onRejected) {
    const self = this;
    return new Promise((resolve, reject) => {
        function handler(callback) {
            try {
                const result = callback(self.data);
                
                if (result instanceof Promise) {
                    result.then(resolve, reject);
                } else {
                    resolve(result);
                }
            } catch (error) {
                reject(error);
            }
        }
        
        if (self.status === PENDING) {
            self.callbacks.push({
                onResolved() {
                    handler(onResolved)
                },
                onRejected() {
                    handler(onRejected)
                }
            })
        } else if (self.status === RESOLVED) {
            setTimeout(() => {
                handler(onResolved);
            });
        } else if (self.status === REJECTED) {
            setTimeout(() => {
                handler(onRejected);
            });
        }
    })
}

6. 异常穿透

 Promise.prototype.then = function (onResolved, onRejected) {
    onResolved = typeof onResolved === 'function' ? onResolved : value => value;
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason };  // 异常穿透的关键
}

7.catch

Promise.prototype.catch = function (onRejected) {
   return this.then(undefined, onRejected);
}

相关推荐:Cnc_zj的《普歌-Promise用法


作者:Cnc_zj
本文源自:Cnc_zj的《自定义promise
本文版权归作者和CSDN共有,欢迎转载,且在文章页面明显位置给出原文链接,未经作者同意必须保留此段声明,否则保留追究法律责任的权利。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值