Created
December 21, 2024 17:09
-
-
Save logie17/0549a318b61e461779d5db31b772cf93 to your computer and use it in GitHub Desktop.
PromiseKeeper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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