Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nested promises in bluebird

I'm trying to figure out how to use promises correctly with the bluebird library. I've come across some nested promises in my code and I noticed that in the bluebird docs it reads:

if you are utilizing the full bluebird API offering, you will almost never need to resort to nesting promises in the first place.

There are many other blog posts about promises being misused and nesting is a regular anti-pattern.

loadCar(someUri) // jqXHR
    .then(function (car) {
        if (carHasFourDoors(car)) {
            loadMake(car.make)
                .then(function (make) {
                    loadModel(make.model)
                        .then(function (model) {
                            loadCarDetails(model)
                        });
                });
        }
        else if (carHasTwoDoors(car)) {
            loadModel(make.model)
                .then(function (model) {
                    loadCarDetails(model)
                });
        }
    });

All of my functions return objects. Looking at the bluebird docs, it seems like there are multiple helper methods: all(), join(), props().

So, my question is: How could I avoid the nesting if there are dependencies? Perhaps this is my misunderstanding of the asynchronous nature of promises. Could something like this work?

Promise.all(loadCar(someUri), loadMake(car.make), loadModel(make.model))
    .then(function(car, make, model) {
        // do logic
    });
like image 687
Jeff Avatar asked Jun 25 '14 15:06

Jeff


People also ask

Can promises be nested?

Nested Promise: Promises give you return statements and error throwing, which you lose with continuation-passing style. A nested promise is when you call child promise inside . then of parent promise and this go-on.

Why do we use Bluebird promises?

The strongest feature of Bluebird is that it allows you to “promisify” other Node modules in order to use them asynchronously. Promisify is a concept applied to callback functions. This concept is used to ensure that every callback function which is called returns some value.

What are the three states of promises in Node JS?

A Promise is in one of these states: pending: initial state, neither fulfilled nor rejected. fulfilled: meaning that the operation was completed successfully. rejected: meaning that the operation failed.

What is .all in Promise?

The Promise.all() method takes an iterable of promises as input and returns a single Promise . This returned promise fulfills when all of the input's promises fulfill (including when an empty iterable is passed), with an array of the fulfillment values.


1 Answers

You always need nesting for control structures, and usually you will need one level of nesting for the function expressions passed to then(). It's not totally avoidable, but can be reduced significantly.

In your case, you even can omit some of the function expressions and pass the functions directly.

loadCar(someUri).then(function (car) {
    if (carHasFourDoors(car)) {
        return loadMake(car.make)
    else if (carHasTwoDoors(car))
        return make; // not sure actually where you get this from
}).then(function (make) {
    return loadModel(make.model)
}).then(loadCarDetails)
like image 113
Bergi Avatar answered Oct 20 '22 05:10

Bergi