Primose的基本实现及核心思想

Promise 实现

const Pending = 'pending';
const Fulfilled = 'fulfilled';
const Rejected = 'rejected';

//把观察者抽象成方法的观察者模式
class MyPromise {
    constructor(executor) {
        this.status = Pending;

        this.value = undefined;
        this.reason = undefined;

        this.onFulfilledCallbacks = [];
        this.onRejectedCallbacks = [];

        const resolve = value => {
            if (this.status !== Pending) return;
            this.status = Fulfilled;
            this.value = value;
            this.onFulfilledCallbacks.forEach(callback => {
                callback(value);
            });
        };

        const reject = reason => {
            if (this.status !== Pending) return;
            this.status = Rejected;
            this.reason = reason;
            this.onRejectedCallbacks.forEach(callback => {
                callback(reason);
            });
        };

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

    then(onFulfilled, onRejected) {
        if (this.status === Fulfilled) {
            onFulfilled(this.value);
        } else if (this.status === Rejected) {
            onRejected(this.reason);
        } else if (this.status === Pending) {
            onFulfilled(this.value);
            onRejected(this.reason);
        }
    }
}

const p1 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('success');
    }, 1000);
});

p1.then(value => {
    console.log('p1 resolved with', value);
});
  • 目前没有实现 链式调用 ,可以发现 Promise 是对 观察者模式 的改造

  • 订阅者对象 抽象成了 方法,通过 then 方法 订阅更新

  • 被观察者 不是 Promise ,而是由外部定义,通过回调 resolve reject发布更新

链式调用,修改 then 方法

then(onFulfilled, onRejected) {
    // 为了方便描述 接下来都用成功情况进行说明
    // 链式调用的核心 就是 then 方法返回一个新的 promise实例 下文称nextPromise
    // 当前的promise实例称 currentPromise
    // resolve 函数被调用时 promise实例 会被 完成
    const nextPromise = new MyPromise((resolve, reject) => {
        // 如果 异步已经结束 状态已经被修改
        // 则 直接完成 nextPromise
        // 结果是 currentPromise的结果经过 currentPromise 的 onFulfilled 处理后的返回值
        if (this.status === Fulfilled) {
            resolve(onFulfilled(this.value));
        } else if (this.status === Rejected) {
            reject(onRejected(this.reason));
        }
        // 如果 异步没有结束 状态还是Pending
        // 则 会在 currentPromise 订阅更新 也就是插入一个方法 跟原来一样
        // 但插入的方法有些改变
        // 插入的方法为 完成 nextPromise
        // nextPromise的结果 是 currentPromise的结果经过 currentPromise 的 onFulfilled 处理后的返回值
        //跟直接完成时一样,只是不立刻执行,而是加入 currentPromise 的 回调队列中,也就是订阅的更新中
        else if (this.status === Pending) {
            this.onFulfilledCallbacks.push(() => resolve(onFulfilled(this.value)));
            this.onRejectedCallbacks.push(() => reject(onRejected(this.reason)));
        }
    });
    return nextPromise;
}

const p1 = new MyPromise((resolve, reject) => {
    setTimeout(() => {
        resolve('success');
    }, 1000);
});

//p1 是 currentPromise p2 是 nextPromise
const p2 = p1.then(value => {
    console.log('p1 resolved with', value);
    return 'p2';
});

//p2 是 currentPromise
p2.then(value => {
    console.log('p2 resolved with', value);
});
  • 链式调用的核心就是对 订阅的更新(方法) 进行封装
  • 在运行回调的同时, 完成 新返回的实例 ,将 回调的返回值 作为 新返回的实例结果

在这里插入图片描述

当前promie的回调队列里加入了 完成新返回的promise的函数 这一行为建立了两个pormise的联系,实现了链式调用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值