Skip to content

Instantly share code, notes, and snippets.

@aniketchanana
Created April 3, 2023 18:33
Show Gist options
  • Save aniketchanana/bc6fad5f942319d7bc6559c9944c0593 to your computer and use it in GitHub Desktop.
Save aniketchanana/bc6fad5f942319d7bc6559c9944c0593 to your computer and use it in GitHub Desktop.
my implementation for promises in javascript
enum STATES {
PENDING = 0,
FULFILLED = 1,
REJECTED = 2,
}
class MyPromise {
private state: STATES;
private value: any;
private handlers: Array<{ onSuccess: Function; onFailure: Function }>;
constructor(
callback: (
resolve: (value: any) => void,
reject: (value: any) => void
) => void
) {
this.state = STATES.PENDING;
this.value = undefined;
this.handlers = [];
try {
callback(this.resolve, this.reject);
} catch (e) {
this.reject(e);
}
}
private resolve = (value: any) => {
this.handleUpdate(STATES.FULFILLED, value);
};
private reject = (value: any) => {
this.handleUpdate(STATES.REJECTED, value);
};
private handleUpdate(state: STATES, value: any) {
if (state === STATES.PENDING) {
return;
}
setTimeout(() => {
if (value instanceof MyPromise) {
return value.then(this.resolve, this.reject);
}
this.state = state;
this.value = value;
this.executeHandlers();
}, 0);
}
private executeHandlers() {
if (this.state === STATES.PENDING) {
return;
}
this.handlers.forEach((handler) => {
if (this.state === STATES.FULFILLED) {
return handler.onSuccess(this.value);
}
handler.onFailure(this.value);
});
}
private addHandler(handler) {
this.handlers.push(handler);
this.executeHandlers();
}
public then(onSuccessCallback, onFailureCallback = null) {
return new MyPromise((resolve, reject) => {
this.addHandler({
onSuccess: (value) => {
if (!onSuccessCallback) {
return resolve(value);
}
try {
return resolve(onSuccessCallback(value));
} catch (e) {
return reject(e);
}
},
onFailure: (error) => {
if (!onFailureCallback) {
return reject(error);
}
try {
return reject(onFailureCallback(error));
} catch {
return reject(error);
}
},
});
});
}
public catch(onFailureCallback) {
return this.then(null, onFailureCallback);
}
public finally(finallyCallback) {
return new MyPromise((resolve, reject) => {
let wasResolved;
let value;
this.then((v) => {
value = v;
wasResolved = true;
return finallyCallback();
}).catch((err) => {
value = err;
wasResolved = false;
return finallyCallback();
});
if (wasResolved) {
resolve(value);
} else {
reject(value);
}
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment