美文网首页
八(2)Promise模拟(姜) ------ 2020-05-

八(2)Promise模拟(姜) ------ 2020-05-

作者: 自己写了自己看 | 来源:发表于2020-05-19 22:06 被阅读0次

1、基础的Promise的实现

const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

class Promise {
    constructor(executor) {
        this.value = undefined;
        this.reason = undefined;
        this.status = PENDING;
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = [];
        let resolve = value => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = FULFILLED;
                this.onResolvedCallbacks.forEach(fn => fn());
            }
        }
        let reject = reason => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = REJECTED;
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        }

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

    then(onFulfilled, onRejected) {
        if (this.status === FULFILLED) {
            onFulfilled(this.value);
        }

        if (this.status === REJECTED) {
            onRejected(this.reason)
        }

        if (this.status === PENDING) {
            this.onResolvedCallbacks.push(() => {
                onFulfilled(this.value);
            })
            this.onRejectedCallbacks.push(() => {
                onRejected(this.reason)
            })
        }
    }
}

module.exports = Promise;

2、实现then的链式调用

const PENDING = 'PENDING';
const FULFILLED = 'FULFILLED';
const REJECTED = 'REJECTED';

const resolvePromise = (promise2, x, resolve, reject) => {
    if (promise2 === x) { // 第一个 .then 中返回第二个promise 本身
        return reject(new TypeError(`chaining cycle for promise #<Promise>`));
    }

    if ((typeof x === 'object' && x !== null) || (typeof x === 'function')) {
        // 可能是Promise
        try {
            let then = x.then;

            if (typeof then === 'function') {
                then.call(x, y => { // 使用第一次获取的 then方法执行,防止第二次取的 then 报错
                    // y有可能还是个promise
                    resolvePromise(promise2, y, resolve, reject);
                }, r => {
                    reject(r);
                }
            }
        } catch (error) {
            // x.then 直接报错了 defineProperty 设置 get 直接在get中 throw error()
            reject(error);

        }

    } else {
        // 不是 Promise
        resolve(x);
    }

}


class Promise {
    constructor(executor) {
        this.value = undefined;
        this.reason = undefined;
        this.status = PENDING;
        this.onResolvedCallbacks = [];
        this.onRejectedCallbacks = [];

        let resolve = value => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = FULFILLED;
                console.log('成功')
                this.onResolvedCallbacks.forEach(fn => fn());
            }
        }

        let reject = reason => {
            if (this.status === PENDING) {
                this.value = value;
                this.status = REJECTED;
                console.log('失败');
                this.onRejectedCallbacks.forEach(fn => fn());
            }
        }

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

    then(onFulfilled, onRejected) {
        let promise2 = new Promise((resolve, reject) => {

            if (this.status === FULFILLED) {
                setTimeout(() => {
                    try {
                        let x = onFulfilled(this.value);
                        resolvePromise(promise2, x, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            }

            if (this.status === REJECTED) {
                setTimeout(() => {
                    try {
                        let x = onRejected(this.reason)
                        resolvePromise(promise2, y, resolve, reject)
                    } catch (error) {
                        reject(error)
                    }
                })
            }

            if (this.status === PENDING) {
                this.onResolvedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onFulfilled(this.value);
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    })
                })
                this.onRejectedCallbacks.push(() => {
                    setTimeout(() => {
                        try {
                            let x = onRejected(this.reason);
                            resolvePromise(promise2, x, resolve, reject)
                        } catch (error) {
                            reject(error)
                        }
                    })
                })
            }
        });

        return promise2;
    }
}

module.exports = Promise;

相关文章

网友评论

      本文标题:八(2)Promise模拟(姜) ------ 2020-05-

      本文链接:https://www.haomeiwen.com/subject/xdbpnhtx.html