Promise override causes then calls to error

折月煮酒 提交于 2020-12-13 07:56:18

问题


I have the following sample code.

class test extends Promise {
    constructor(executor) {
        super(executor)
    }

    static getPromise() {
        return new test((res, rej) => {
            res(true)
        })
    }
}

let t = test.getPromise()
t.then(value => {console.log("Works")}, 
       value => {console.log("Works")})

this works just fine, but if I were to put the same function directly into the super function, it throws an error.

class test extends Promise {
    constructor(executor) {
        super((res, rej) => {
            res(true)
        })
    }

    static getPromise() {
        return new test((res, rej) => {
            res(true)
        })
    }
}

let t = test.getPromise()
t.then(value => {console.log("Works")}, 
       value => {console.log("Works")})

the error is TypeError: Promise resolve or reject function is not callable Why is this happening, aren't these two pieces of code equivalent?

My goal is to simplify use of my library by simply having:

let t = new test()
t.then(value => {console.log("Works")}, 
       value => {console.log("Works")})

I understand this is not much of a simplification, I am ok with keeping the static function if required, but I am more curious as to why this is not working.

my questions are:

  1. Why are these not equivalent, and why is this erroring?
  2. How can I make this work as I expect?

EDIT:

Thanks to Bergi, I came to the realization that the promise class I am overriding is using the test constructor for the "then" functions. While I was assuming it was using the original constructor. It is obvious in hindsight, but my fix ended up being simply adding this to the constructor.

if(!executor) executor = (res, rej) => { res(true) }

回答1:


Why are these not equivalent, and why is this erroring?

Your overridden constructor does never call the executor and pass it the promise resolving functions (resolve and reject). They are important! You cannot subclass Promise and change the interface like that.

Why does this throw an error when you call new test() that doesn't use the constructor? It does not. It throws the error when you call t.then(…), which tries to construct a new promise (for its return value) and uses t's constructor for that. It does pass a proper executor callback, and expects it to be called synchronously with resolve and reject - which your code does not do. After the call, it bitches about not having got two functions.

How can I make this work as I expect?

Don't use promise subclassing. There's no reason for it. You just want to have a normal function that returns a promise. Use

const test = {
    getPromise() {
        return Promise.resolve(true)
    }
};
test.getPromise().then(…);

or

function test() {
    return Promise.resolve(true);
}
test().then(…);


来源:https://stackoverflow.com/questions/47312427/promise-override-causes-then-calls-to-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!