Javier Manzano
Javier Manzano

Reputation: 4821

Avoid function to return before Promise ends

inside a function I have something like this

function() {
var User = new Models.CommerceUser();
var userPromise = User.fetch();
userPromise
    .done(function() {
        console.log('user fetched')
        var CommerceCollection = new Models.CommerceCollection();
        var commercePromise = CommerceCollection.fetch({
            data: {
                noCursor: true
            }
        });
        commercePromise
            .done(function() {
                console.log('commerces fetched')
                var ActiveOffersCollection = new Models.ActiveOffersCollection();
                var activeOffersPromise = ActiveOffersCollection.fetch();
                activeOffersPromise
                    .done(function() {
                        console.log('activeOffers fetched')
                        initVariables();
                    })
                    .error(function() {
                        console.error('Error while getting commerces')
                    });

            })
            .error(function() {
                console.error('Error while getting commerce')
            })
    })
 return result;
  }

I don't want to return before all the callbacks have finished, but I really don't know how to do it.

For those who are asking... These are backbone models and that's why I have promises :)

Thanks in advance

Upvotes: 0

Views: 93

Answers (1)

Jon
Jon

Reputation: 437474

You don't have an option to do that. The operations you invoke are asynchronous, so if your own code depends on their results it cannot work in a synchronous manner.

Without taking into account the return result (what does that do? there is no result defined anywhere!), you should restructure your code into a pipeline. Start from the contents of your function:

userPromise
.done(function() {
    console.log('user fetched')
    var CommerceCollection = new Models.CommerceCollection();
    var commercePromise = CommerceCollection.fetch({
        data: {
            noCursor: true
        }
    });
    commercePromise
        .done(function() {
            console.log('commerces fetched')
            var ActiveOffersCollection = new Models.ActiveOffersCollection();
            var activeOffersPromise = ActiveOffersCollection.fetch();
            activeOffersPromise
                .done(function() {
                    console.log('activeOffers fetched')
                    initVariables();
                })
                .error(function() {
                    console.error('Error while getting commerces')
                });

        })
        .error(function() {
            console.error('Error while getting commerce')
        })
})

Instead of waiting for each promise to complete and then schedule the next step (there are three levels of doing this here), compose the pipeline with then:

// error checking elided
return new Models.CommerceUser().fetch()
   .then(function() { return new Models.CommerceCollection().fetch(...); })
   .then(function() { return new Models.ActiveOffersCollection.fetch(...); })
   .then(initVariables);

Returning the new composed promise from your function and further chain code to it.

Upvotes: 1

Related Questions