0

I'm building my first ionic/angularjs. My app consists of several sequential stages, each has a DB query in search of a pattern. So each stage is basically a while loop that breaks when the pattern is found at the db. I have a whileloop with promises following this post. I have a problem with chaining while loops.

Utils.promiseWhile = function(condition, body) {
  var done = $q.defer(); //also tried: new $q.defer();
  function loop() {
    if (!condition()) return done.resolve();
    $q.when(body(), loop, done.reject);
  }
  setTimeout(loop, 1);
  return done.promise;
}

A single while loop works as expected, returns 11 txt entries from the async DB. The loop condition in this example is simply the loop count, I removed the real pattern code for simplicity. The logged console is: L1:0, L1:1, .., L1:12, done1. That's just fine.

The problem shows when I chain loops:

var idx1 = 0;
var idx2 = 0;
var idx3 = 0;
var txt ='';
Utils.promiseWhile(
    function () { console.log("L1: "+idx1); return idx1 <= 11;},
    function () {
    idx1++;
    return MYDB.txt(idx1,1)
            .then(function(t){txt += (' '+t);});
})
.then(function () {
    console.log("done1");
    Utils.promiseWhile(
        function () { console.log("L2: "+idx2); return idx2 <= 11;},
        function () {
        idx2++;
        return MYDB.txt(idx2,1)
                .then(function(t){txt += (' '+t);});
    })
})  
.then(function () {
    console.log("done2");
    Utils.promiseWhile(
        function () { console.log("L3: "+idx3); return idx3 <= 11;},
        function () {
        idx3++;
        return MYDB.txt(idx3,1)
                .then(function(t){txt += (' '+t);});
    })
})
.then(function(){
    console.log("done3");
});

The unexpected output is:

L1: 0
L1: 1
L1: 2
L1: 3
L1: 4
L1: 5
L1: 6
L1: 7
L1: 8
L1: 9
L1: 10
L1: 11
L1: 12
done1
done2
done3
L2: 0
L3: 0
L2: 1
L3: 1
L2: 2
L3: 2
L2: 3
L3: 3
L2: 4
L3: 4
L2: 5
L3: 5
L2: 6
L3: 6
L2: 7
L3: 7
L2: 8
L3: 8
L2: 9
L3: 9
L2: 10
L3: 10
L2: 11
L3: 11
L2: 12
L3: 12

Why are L2 and L3 running in parallel?

Community
  • 1
  • 1
Tarek Eldeeb
  • 588
  • 2
  • 6
  • 24

1 Answers1

1

One problem is that your outer thens doesn't return any promises.

I believed until now that you would get unresolved promises, but that can't be true since you observe tasks running in parallel.

Another problem is that it's very hard to see what you are trying to do, when you are mixing both nested and chained promises. Why do you need a promiseWhile in the first place?

Thomas Eyde
  • 3,820
  • 2
  • 25
  • 32
  • Thanks `return Utils.promiseWhile(...` in the outer thens fixed it. My app really needs this behavior. I have several sequential stages where each stage searches for a patter in an asynchronous DB. – Tarek Eldeeb Dec 29 '15 at 16:15
  • I'm sure you need the behavior, that's not what I meant. `promiseWhile` seems to flag when a background loop is terminated, but does not return any value. Then you mitigate that by wrapping this promise into another promise which returns the value. I feel there is one promise too many in there. – Thomas Eyde Jan 01 '16 at 03:21