I'm trying to implement my own promise in JavaScript. Below is my class.
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 = [];
}
}
If I call the code below, it works fine
const testPromise = new MyPromise((resolve, reject) => {
setTimeout(() => resolve(10));
});
const firstCall = testPromise.then((value) => {
console.log(value)
return value+1;
});
However, if I add a second then
to my firstCall request as below:
const firstCall = testPromise.then((value) => {
console.log(value)
return value+1;
}).then((newVal) => {
console.log(newVal)
});
I got the error TypeError: Cannot read property 'then' of undefined
. Does anyone know why it is happening?
Thanks