Reputation: 1021
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++;
}
}
Upvotes: 5
Views: 2892
Reputation: 25552
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
}
}
});
}
Upvotes: 5