Skip to content

Instantly share code, notes, and snippets.

@gsrai
Created June 21, 2018 06:17
Show Gist options
  • Save gsrai/cde6fa753b4e4edde4652c03f4df42e7 to your computer and use it in GitHub Desktop.
Save gsrai/cde6fa753b4e4edde4652c03f4df42e7 to your computer and use it in GitHub Desktop.
Simple Promise Impl to help understand promises
// simplified promise implementation for learning purposes
// https://levelup.gitconnected.com/understand-javascript-promises-by-building-a-promise-from-scratch-84c0fd855720
class MyPromise {
constructor(promiseCallback) {
this.promiseChain = []
this.handleError = () => {}
// bind this as onResolve and onReject callbacks are passed into the promise callback
this.onResolve = this.onResolve.bind(this)
this.onReject = this.onReject.bind(this)
promiseCallback(this.onResolve, this.onReject)
}
then(onResolve) {
this.promiseChain.push(onResolve)
return this
}
catch(handleError) {
this.handleError = handleError
return this
}
// in reality you should not loop through the promise chain immediately but only on the resolved values
// in this implementation you cannot return promises in the then chain
onResolve(value) {
let storedValue = value
try {
this.promiseChain.forEach((nextFunc) => {
storedValue = nextFunc(storedValue)
})
} catch(error) {
this.promiseChain = []
this.onReject(error)
}
}
onReject(error) {
this.handleError(error)
}
}
// contrived fetch implementation for the purposes of the example
const myFetch = () => {
return new MyPromise((resolve, reject) => {
setTimeout(() => {
const apiResponse = mockApiBackend()
if (apiResponse.statusCode >= 400) {
reject(apiResponse)
} else {
resolve(apiResponse.data)
}
}, 5000)
})
}
const mockApiBackend = () => {
const user = {
username: 'gsrai',
age: 24,
yearOfBirth: 1994
}
if (Math.random() > 0.05) {
return {
data: user,
statusCode: 200
}
} else {
return {
statusCode: 404,
message: 'Could not find User',
error: 'Not Found'
}
}
}
function main() {
myFetch().then(user => {
console.log('first then(), ', user.username)
return user
}).then((user) => {
console.log(`User ${user.username}'s favorite number is ${user.age}`)
return user
}).then((user) => {
console.log('The previous .then() told you the age')
return user.yearOfBirth
}).then((year) => {
console.log(`Their year of birth is ${year}`)
})
.then(() => {
console.log('This is the last then()')
})
.catch((error) => {
console.log(error.message)
})
}
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment