Question

I need to pause a for loop and not continue until I specify. For each item in the array that I'm looping through, I run some code that runs an operation on a separate device, and I need to wait until that operation is finished before looping to the next item in the array.

Fortunately, that code/operation is a cursor and features an after: section.

However, it's been running the entire for loop instantly, which I need to prevent. Is there any way to prevent the loop from continuing until specified? Or perhaps a different type of loop or something that I should use?

My first (poor) idea was to make a while-loop within the for-loop that ran continuously, until the after: portion of the cursor set a boolean to true. This just locked up the browser :( As I feared it would.

Anything I can do? I'm fairly new to javascript. I've been enjoying my current project though.

Here's the while-loop attempt. I know it's running the entire loop immediately because the dataCounter goes from 1 to 3 (two items in the array currently) instantly:

if(years.length>0){
  var dataCounter = 1;
  var continueLoop;
  for(var i=0;i<years.length;i++){
    continueLoop = false;
    baja.Ord.make(historyName+"?period=timeRange;start="+years[i][1].encodeToString()+";end="+years[i][2].encodeToString()+"|bql:select timestamp, sum|bql:historyFunc:HistoryRollup.rollup(history:RollupInterval 'hourly')").get(
        {
          ok: function (result) {
          // Iterate through all of the Columns

          baja.iterate(result.getColumns(), function (c) {
            baja.outln("Column display name: " + c.getDisplayName());
          });
        },
        cursor: {
          before: function () {
          baja.outln("Called just before iterating through the Cursor");
          counter=0;
          data[dataCounter] = [];
          baja.outln("just made data["+dataCounter+"]");
        },
        after: function () {
          baja.outln("Called just after iterating through the Cursor");
          continueLoop = true;
        },
        each: function () {

          if(counter>=data[0].length) {
            var dateA = data[dataCounter][counter-1][0];
            dateA += 3600000;
          }
          else {
            var dateA = data[0][counter][0];
          }

          var value=this.get("sum").encodeToString();
          var valueNumber=Number(value);

          data[dataCounter][counter] = [dateA,valueNumber];
          counter++;
        },
        limit: 744, // Specify optional limit on the number of records (defaults to 10)2147483647
        offset: 0 // Specify optional record offset (defaults to 0)
        }
        })
        while(continueLoop = false){
          var test = 1;
          baja.outln("halp");
        }
    dataCounter++;
  }
}
Was it helpful?

Solution

Do not use a for loop to loop on each element. You need, in the after: to remember which element of the array you've just done and then move to the next one.

Something like this :

var myArray = [1, 2, 3, 4]

function handleElem(index) {
    module.sendCommand({
        ..., // whatever the options are for your module
        after: function() {
            if(index+1 == myArray.length) {
                return false; // no more elem in the array
            } else {
                handleElem(index+1)}  // the after section
            }
    });
}

handleElem(0);

I assumed that you call a function with some options (like you would for $.ajax()) and that the after() section is a function called at the end of your process (like success() for $.ajax())

If the "module" you call is not properly ended in the after() callback you could use setTimeout() to launch the process on the next element with a delay

EDIT: With your real code it would be something like this :

function handleElem(index) {
    baja.Ord.make("...start="+years[index][1].encodeToString()+ "...").get(
    {
        ok: ...
        after: function() {
            if(index+1 == years.length) {
                return false; // no more elem in the array
            } else {
                handleElem(index+1)}  // the after section
            }
        }
    });
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top