【问题标题】:Implementing my own Promise in JavaScript在 JavaScript 中实现我自己的 Promise
【发布时间】:2021-10-24 07:03:23
【问题描述】:

我正在尝试在 JavaScript 中实现我自己的承诺。下面是我的课。

const states = {
    PENDING: "pending",
    FULFILLED: "fulfilled",
    REJECTED: "rejected"
}

class MyPromise {
    constructor(computation) {
        this.state = states.PENDING
        this.value = undefined;
        this.error = undefined;

        this.thenQueue = [];

        if(typeof computation === 'function') {
            setTimeout(() => {
                try {
                    computation(
                        this.onFulFilled.bind(this),
                        this.onReject.bind(this)
                    );
                } catch(ex) {
                    this.onReject.bind(this);
                }
            });
        }
    }

    then = (fullfilledFn, catchFn) => {
        const promise = new MyPromise();
        this.thenQueue.push([promise, fullfilledFn, catchFn]);
        if(this.state === states.FULFILLED) {
            this.propageFulFilled()
        } else if(this.state == states.REJECTED) {
            this.propageRejected();
        }
    }

    catch = (catchFn) => {
        return this.then(undefined, catchFn);
    }

    onFulFilled = (value) => {
        if(this.state === states.PENDING) {
            this.state = states.FULFILLED;
            this.value = value;
            this.propageFulFilled();
        }
    }

    onReject = (error) => {
        if(this.state === states.PENDING) {
            this.state = states.REJECTED;
            this.error = error;
            this.propageRejected();
        }
    }

    propageFulFilled = () => {
        for(const [promise, fullFilledFn] of this.thenQueue) {
            const result = fullFilledFn(this.value);
            if(typeof result === 'MyPromise') {
                promise.then(
                    value => promise.onFulFilled(value),
                    error => promise.onReject(error)
                )
            } else {
                promise.onFulFilled(result);    // final result
            }
        }
        this.thenQueue = [];
    }

    propageRejected = () => {
        for(const [promise, undefined, catchFn] of this.thenQueue) {
            const result = catchFn(this.value);
            if(typeof result === 'MyPromise') {
                promise.then(
                    value => promise.onFulFilled(value),
                    error => promise.onReject(error)
                )
            } else {
                promise.onFulFilled(result);    // final result
            }
        }
        this.thenQueue = [];
    }
}

如果我调用下面的代码,它可以正常工作

const testPromise = new MyPromise((resolve, reject) => {
    setTimeout(() => resolve(10));
});

const firstCall = testPromise.then((value) => {
    console.log(value)
    return value+1;
});

但是,如果我在 firstCall 请求中添加第二个 then,如下所示:

const firstCall = testPromise.then((value) => {
    console.log(value)
    return value+1;
}).then((newVal) => {
    console.log(newVal)
});

我收到错误 TypeError: Cannot read property 'then' of undefined。有谁知道为什么会这样?

谢谢

【问题讨论】:

  • 在你的 .then() 方法中应该返回 this 这是自己的实例,这样你就可以创建一个 chain 函数,像这样 stackoverflow.com/a/7730373/9816472
  • .then() 必须返回一个链接到当前承诺的新承诺。

标签: javascript promise


【解决方案1】:

您的 then 函数没有返回任何内容:

then = (fullfilledFn, catchFn) => {
    const promise = new MyPromise();
    this.thenQueue.push([promise, fullfilledFn, catchFn]);
    if(this.state === states.FULFILLED) {
        this.propageFulFilled()
    } else if(this.state == states.REJECTED) {
        this.propageRejected();
    }
    return promise;
}

【讨论】:

  • 如果我这样做,我不会得到错误,但它不能正常工作。 const testPromise = new MyPromise((resolve, reject) => { setTimeout(() => resolve(10)); }).then((value) => { console.log(value) return 2*value; }).then((newVal) => { console.log(newVal) }); 两次打印 10。第二次调用应该是 20
  • .then() 必须返回一个链接到原始承诺的新承诺,而不是返回原始承诺。
  • 我明白了。谢谢
猜你喜欢
  • 1970-01-01
  • 2018-03-16
  • 1970-01-01
  • 1970-01-01
  • 2015-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-28
相关资源
最近更新 更多