Skip to content

Instantly share code, notes, and snippets.

@logie17
Created December 21, 2024 17:09
Show Gist options
  • Save logie17/0549a318b61e461779d5db31b772cf93 to your computer and use it in GitHub Desktop.
Save logie17/0549a318b61e461779d5db31b772cf93 to your computer and use it in GitHub Desktop.
PromiseKeeper
class PromiseKeeper {
constructor(executor) {
this.state = 'pending',
this.callbacks = [];
const resolve = value => {
if (this.state !== 'pending') return;
this.state = 'fulfilled';
this.value = value;
for (const cb of this.callbacks) {
cb.onFullfilled(value);
}
};
const reject = value => {
if (this.state !== 'pending') return;
this.state = 'rejected';
this.value = value;
for (const cb of this.callbacks) {
cb.onRejected(value);
}
}
try {
executor(resolve, reject);
} catch(e) {
reject(e);
}
}
then(onFulfilled, onRejected) {
return new PromiseKeeper((resolve, reject) => {
const handleCallback = () => {
try {
if (this.state == 'fulfilled') {
const result = onFulfilled ? onFulfilled(this.value): this.value
resolve(result);
} else if (this.state == 'rejected') {
const result = onRejected ? onRejected(this.value) : reject(this.value);
resolve(result);
}
} catch(e) {
reject(e);
}
}
if (this.state == 'pending') {
this.callbacks.push({
onFullfilled: () => handleCallback(),
onRejected: () => handleCallback()
})
} else {
handleCallback();
}
});
}
catch(onRejected) {
return this.then(null, onRejected);
}
finally(onFinally) {
return this.then(
(value) => {
onFinally && onFinally();
return value;
},
(reason) => {
onFinally && onFinally();
throw reason;
}
);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment