1

I tried to implement a promise function that, after a request to an external api, checks in my database if an object exists and in negative case, it saves it. I use this function with an array passed in a Q.all and I see that all the objects are saved in the same time, so the check fail every time and I have duplicate objects. How can I run the promises passed in the Q.all sequentially and not in parallel? This is the code: finalCuts is an array of objects that have a reference with customers.

request.findNewCustomer().then(function(customers) {
    Q.all(finalCuts.map(function(currFinalCut) {
        return checkAndSetCustomer(currFinalCut._id,currFinalCut.customerCod,customers)
     }));
});

checkAndSetCustomer = function(cutId,cod,customers) {
     var deferred = Q.defer();
     Customer.findByIdentity(cod).then(function(customer) {
         if (customer && customer.cod == cod) {
               Cut.addCustomerToCut(customer._id,cutId).then(function(result) {
                deferred.resolve(result);
            });
         } else {
            customers.forEach(function(currCustomer) {
                 if (currCustomer.cod == cod) {
 Customer.saveNewCustomer(currCustomer).then(function (customer) {
        Cut.addCustomerToCut(customer._id, cutId).then(function (cut) {
                            deferred.resolve(cut);
                        })
                    })
                }
return deferred.promise;

So, if in the finalCuts array I have some object with the field code for example [c1: 12, c2: 14, c3: 14], after the execution of this function in my database I will have two customer with code 14.

3 Answers3

0

Q.all runs all of the promises at once, not sequentially. If you wish to run them sequentially, you should queue them up like:

func1().then(function() {
   ...
   return func2();
}).then(function() {
   ...
   return func3();
})
... etc

when func1,func2,func3,... returns promises

AlexD
  • 4,062
  • 5
  • 38
  • 65
0

This is not the answer for this question, but the answer for your problem. If you would like to "do things in chain", then q is not the best for it. You should use RxJS framework for that.

Read more here -> https://github.com/Reactive-Extensions/RxJS

Andras Szell
  • 527
  • 2
  • 13
0

You can chain the calls as described in the Sequences section of the Q documentation:

var result = Q(null);
finalCuts.forEach(function(currFinalCut) {
    result = result.then(function(){
        return checkAndSetCustomer(currFinalCut._id,currFinalCut.customerCod,customers);
    });
});
Alexander Kravets
  • 4,245
  • 1
  • 16
  • 15