简体   繁体   中英

Avoiding callback hell in promises using nodejs

I have written about a half a dozen functions in nodejs using promises, i want really post all of that code, instead i will post a simulated example , so i can encapsulate my problem succinctly. so say i have 2 functions below:

foo = () => {
    return new Promise( ( r , rj ) => {
       setTimeout( () => {
             r('DONE');
       }, 3000 );
    }); 
}  

And

bar = () => {
    return new Promise( (r , rj) => { r('ALL DONE !') } )
}

Now i would like to avoid the callback hell and do the following:

foo().then( (resp) => console.log(resp) ).bar()

Instead what i am forced to do is this:

foo().then( (resp) => { console.log(resp); bar() } )

So basically in my production code i have something like the below, so far(just to give you an idea):

let uploadToVault = ( INPUT_DIR , VOLT_CRED ) => {

    INPUT_DIRECTORY = INPUT_DIR;
    VOLT_CREDENTIALS = VOLT_CRED;

    volt_APILogin().then( () => {
        volt_getProduct().then( () => {
           volt_CreatePresentation().then( (resp) => {
                console.log(resp);        
                volt_uploadSlides().then( (resp) => {
                    console.log(resp);
                    volt_bindSlide().then( (resp) => {
                        console.log(resp);
                    });
                });
           });  
        });
    });
}

Now how can i write this in more a chain format vs writing this in a callback ?

The idea would be to always return a promise:

volt_APILogin()

    .then(() => {
        return volt_getProduct();
    })
    .then(() => {
         return volt_CreatePresentation();
    })
    .then((resp) => {
         console.log(resp);        
         return volt_uploadSlides();
    })
    .then((resp) => {
         console.log(resp);
         return volt_bindSlide();
    })
    .then((resp) => {
         console.log(resp);
         return Promise.resolve('just for fun');
    })
    .then((resp) => {
         console.log("This round is", resp);
    });

Then, if there are intermediary values you need to use down the chain, just collect them to variables outside the chain.

A tip is to check out the async/await syntax. It basically makes it possible to write asynchronous code that looks like synchronous code.

So, if you have this function:

bar = () => {
    return new Promise( (r , rj) => { r('ALL DONE !') } )
}

Then you can call it like this:

let fizz = async () => {
    const result = await bar();
    console.log(`Bar said: ${result}`);
};

For error handling, you would wrap your awaiting function calls in a try-catch block:

    try {
        const result = await bar();
        console.log(`Bar said: ${result}`);
    } catch {
        // Handle the error
    }

Check out this link for more info: https://javascript.info/async-await (Or just google "js async await" and you will find tons more :))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM