How to solve callback hell with Promise

This is the 20th day of my participation in the First Challenge 2022, for more details: First Challenge 2022 “.

Introduction:

How to use the thunk function to solve callback hell? . There are many ways to solve callback hell, and this article discusses how to use Promise to solve callback hell.

Write a callback hell

const fn = (str, callback) => {
    setTimeout(() => {
        console.log(str)
        callback(str)
    }, 100);
}

fn('1', () => {
    fn('2', () => {
        fn('3', () => {
            fn('4', () => {
                console.log('done')
            })
        })
    })
})
Copy the code

The FN call here forms a welcome callback hell. Running results:

1
2
3
4
done
Copy the code

The purpose is to pass arguments 1-4 in the asynchronous function fn and execute them in turn.

Construct the Promise factory function

const promiseFactory = (str) => {
    return new Promise((resolve) => {
        fn(str, resolve)
    })
}
Copy the code

The principle is simple, and the main purpose is to separate parameters from callbacks, which is the basic principle for dealing with callback hell. The Promise factory function accepts all arguments except callback, and then calls the original function with promise’s resolve instead of callback. This completes a Promise factory function.

Chain call factory function

promiseFactory('1')
    .then(() => promiseFactory('2'))
    .then(() => promiseFactory('3'))
    .then(() => promiseFactory('4'))
    .then(() => { console.log('done') })
Copy the code

Running results:

1
2
3
4
done
Copy the code

The result is exactly the same as the original callback hell method call, and in fact they are executed in the same order

The complete code

const fn = (str, callback) => { setTimeout(() => { console.log(str) callback(str) }, 100); } // fn('1', () => { // fn('2', () => { // fn('3', () => { // fn('4', () => { // console.log('done') // }) // }) // }) // }) const promiseFactory = (str) => { return new Promise((resolve) =>  { fn(str, resolve) }) } promiseFactory('1') .then(() => promiseFactory('2')) .then(() => promiseFactory('3')) .then(() => promiseFactory('4')) .then(() => { console.log('done') })Copy the code

Multi-parameter callback hell

const fn = (greeting, myName, callback) => { setTimeout(() => { console.log(greeting + ',' + myName) callback() }, 100);  } // fn('1', () => { // fn('2', () => { // fn('3', () => { // fn('4', () => { // console.log('done') // }) // }) // }) // }) const promiseFactory = (greeting, myName) => { return new Promise((resolve) => { fn(greeting, myName, resolve) }) } promiseFactory('hehe', 'ouda') .then(() => promiseFactory('hello', 'ouda1')) .then(() => promiseFactory('hi', 'ouda2')) .then(() => promiseFactory('haha', 'ouda3')) .then(() => { console.log('done') })Copy the code

Running results:

hehe,ouda
hello,ouda1
hi,ouda2
haha,ouda3
done
Copy the code

The same applies in a multi-parameter environment, where the principle is to repackage functions other than callback as factory functions, and then replace the Promise’s resolve with callback.

Eventually, we were able to change the nested callback to a chained call, which is a common way of dealing with callback hell in our development.