5

我需要暂停一个 for 循环并且在我指定之前不要继续。对于我循环遍历的数组中的每个项目,我运行一些在单独设备上运行操作的代码,并且我需要等到该操作完成后才能循环到数组中的下一个项目。

幸运的是,该代码/操作是一个光标并具有一个after:部分。

但是,它会立即运行整个 for 循环,这是我需要防止的。有什么办法可以防止循环继续直到指定?或者也许是不同类型的循环或我应该使用的东西?

我的第一个(糟糕的)想法是在持续运行的 for 循环中创建一个 while 循环,直到after:光标的部分设置booleantrue. 这只是锁定了浏览器:(正如我所担心的那样。

有什么我能做的吗?我对javascript相当陌生。不过,我一直很享受我目前的项目。

这是while-loop尝试。我知道它会立即运行整个循环,因为dataCounterfrom 1to 3(当前数组中的两个项目)会立即运行:

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++;
  }
}
4

1 回答 1

5

不要使用 for 循环来循环每个元素。您需要在after:中记住您刚刚完成的数组的哪个元素,然后移动到下一个元素。

像这样的东西:

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);

我假设你调用一个带有一些选项的函数(就像你想要的那样$.ajax()),并且该after()部分是在你的过程结束时调用的函数(比如success()for $.ajax()

如果您调用的“模块”未在after()回调中正确结束,您可以使用setTimeout()延迟启动下一个元素的进程

编辑:使用您的真实代码,它将是这样的:

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
            }
        }
    });
}
于 2012-12-07T15:51:55.997 回答