JS interview in 2 minutes / Promise
source link: https://dev.to/kozlovzxc/js-interview-in-2-minutes-promise-4fhl
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Question:
What is a Promise?
Quick answer:
It is an object which represents the current state and value of the operation. There are three states for Promises - pending, success, failure.
Longer answer:
Basically, the idea behind the Promises is fairly simple to understand. It is just a container that will only resolve when some calculations are done. That's it.
I guess it will be easier to understand if we just implement it on our own.
class MyPromise {
dataHandlers = []
errorHandler = []
finalHandlers = []
constructor(func) {
// Apply handlers one by one and initialize every following handler with the previouses result
let onResolve = data => this.dataHandlers.reduce(
(acc, onData) => onData(acc),
data
)
// Just call every onReject
let onReject = error => this.errorHandler.reduce(
(_, onError) => onError(error),
undefined
)
// Just call every onFinal
let onFinal = () => this.finalHandlers.reduce(
(_, onFinal) => onFinal(),
undefined
)
// We need to set timeout, so our function
// executed after we set .then, .catch, and .finally
setTimeout(() => {
try {
func(onResolve, onReject)
} catch (error) {
onReject(error)
} finally {
onFinal()
}
}, 0)
}
then(onData, onError) {
if (onData) { this.dataHandlers.push(onData) }
if (onError) { this.errorHandler.push(onError) }
return this
}
catch(onError) {
return this.then(undefined, onError)
}
finally(onFinal) {
if (onFinal) { this.finalHandlers.push(onFinal) }
return this
}
}
Let's test it!
let dataPromise = new MyPromise((resolve, reject) => resolve(2))
dataPromise
.then(res => res + 2)
.then(res => res * 2)
.then(res => console.log(res)) // 8
.finally(() => console.log('Finally!')) // Finally!
.finally(() => console.log('Finally (1)!')) // Finally (1)!
let rejectPromise = new MyPromise((resolve, reject) => reject(2))
rejectPromise
.then(res => res + 2)
.then(res => res * 2)
.then(res => console.log(res))
.catch(error => console.error(error)) // 2
.finally(() => console.log('Finally!')) // Finally!
let throwErrorPromise = new MyPromise((resolve, reject) => { throw new Error('hello') })
throwErrorPromise
.then(res => res + 2)
.then(res => res * 2)
.then(res => console.log(res))
.catch(error => console.error(error)) // hello
.finally(() => console.log('Finally!')) // Finally
// This one will produce two errors instead of one.
// Can you come up with the fix?
let doubleErrorPromise = new MyPromise((resolve, reject) => reject('first'))
doubleErrorPromise
.catch(error => { console.error(error); throw 'second' })
// 'first'
// 'second'
// Uncaught 'second'
// This is how it should work
let fixedDoubleErrorPromise = new Promise((resolve, reject) => reject('first'))
fixedDoubleErrorPromise
.catch(error => { console.error(error); throw 'second' })
// 'first'
// Uncaught 'second'
Real-life applications:
Sometimes it is a bit easier to use async/await syntax
And sometimes you will need Promise helpers functions like Promise.all
Resources:
MDN/Promise
Other posts:
Btw, I will post more fun stuff here and on Twitter. Let's be friends 👋
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK