问题
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:
- Why are these not equivalent, and why is this erroring?
- 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