5

JS interview in 2 minutes / Promise

 3 years ago
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.
neoserver,ios ssh client
JS interview in 2 minutes

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
    }
}
Enter fullscreen modeExit fullscreen mode

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'
Enter fullscreen modeExit fullscreen mode

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 👋


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK