Skip to content

Instantly share code, notes, and snippets.

@VladStepanov
Last active February 9, 2020 11:48
Show Gist options
  • Save VladStepanov/eb5e3b3685516b5fd82928948aa07605 to your computer and use it in GitHub Desktop.
Save VladStepanov/eb5e3b3685516b5fd82928948aa07605 to your computer and use it in GitHub Desktop.
Promise implementation
class MyPromise {
constructor(executor) {
this.state = MyPromise.states.pending
this.queue = {
'resolve': [],
'reject': []
}
try {
executor(this.resolver.bind(this), this.rejecter.bind(this))
} catch (e) {
this.rejecter(e)
}
}
static get states() {
return {
resolve: 'resolved',
reject: 'rejected',
pending: 'pending'
}
}
resolver(payload) {
this.state = MyPromise.states.resolve
let curFn
try {
curFn = this.queue.resolve[0](payload)
} catch (e) {
this.rejecter(e)
}
for (let i = 1; i < this.queue.resolve.length; i++) {
if (curFn instanceof MyPromise) {
curFn.queue.resolve.push(...this.queue.resolve.slice(i))
break;
}
try {
curFn = this.queue.resolve[i](curFn)
} catch (e) {
this.rejecter(e)
}
}
}
rejecter(reason) {
this.state = MyPromise.states.reject
this.queue.reject.forEach(el => el(reason))
}
then(exec = () => { }) {
this.queue.resolve.push(exec)
return this
}
catch(exec = () => { }) {
this.queue.reject.push(exec)
return this
}
}
new MyPromise(function (resolve, reject) {
setTimeout(() => {
resolve("resolved")
// reject('rejected')
}, 2000);
})
.then(payload => delay(payload))
.then(res => console.log(`${res} second`)) // resolved first second
// .catch(err => console.log(err))
function delay(payload) {
return new MyPromise(resolve => {
setTimeout(() => {
resolve(`${payload} delay`)
}, 2000);
})
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment