Extendscript: how to skip current iteration in a for loop?

573 Views Asked by At

I have the following code, written in ExtendScript to process a series of layers in an After Effects composition:

   for (var i=0; i < selectedLayers.length; i++) {
        var layer = selectedLayers[i];
        if (!layer.hasVideo || !layer.enabled) {
             //Go for the next one
             continue;
             }
        //Do stuff
        }

If an element isn't enabled or doesn't have video in it, the loop should skip it; if it does, then it should be processed.

Now, everything works fine if there are no elements that fulfill that "if" check, but if one element fulfills that check… then the loop gets stuck at the next iteration. That is: imagine if the element at i=2 doesn't have video. The "continue" gets executed… and then, the loop gets stuck indefinitely at i=3 and never ends.

Why does this happen? I thought that "continue" is precisely the instruction to skip an iteration of a loop in Javascript/Extendscript. What's going on?

EDIT: as requested, here is my entire code. Maybe I forgot a brace somewhere in one of those nested "if"s… but in that case, how can the code work in some cases and not in others?

var nombreDelPlugin="Denoiser II";

var rutaRender="/Users/paulj";

var activeItem = app.project.activeItem;
if ((activeItem == null) || !(activeItem instanceof CompItem)) {
    alert("Please select or open a composition first.");
    }
else {
    var selectedLayers = activeItem.selectedLayers;
    if (activeItem.selectedLayers.length == 0) {
        alert("Please select at least one layer in the active comp first.");
        }
    else {
        var comp = app.project.activeItem;
        var width=comp.width;
        var height=comp.height;
        var par=comp.pixelAspect;
        var fps=comp.frameRate;

        var tempFolder = comp.parentFolder.items.addFolder(comp.name + " - Temp Comps");
        var ClipsAnadidos=Array();
        var nombresUsados={};

        for (var i=0; i < selectedLayers.length; i++) {
            alert("Mooo: " + i);
            var layer = selectedLayers[i];
            if (!layer.hasVideo || !layer.enabled) {
                    alert("Meeept: " + i);
                    continue;
                   }
  /*          if (!esFootage(layer)) {
                alert("Meeept: " + i);
                break;
                }
*/
            //¿Hemos renderizado ya este layer? Si es así, nos lo saltamos.
            var original=layer.source;
            if (inArray(original, ClipsAnadidos) > 0) {
                continue;
                }
           ClipsAnadidos.push(original);

           //¿Hay otra comp ya con este mismo nombre?
           var vecesUsado=nombresUsados[original.name];
           if (!vecesUsado) { vecesUsado=0; }
            var nombre= original.name + "_" + vecesUsado;
            nombresUsados[original.name]=vecesUsado + 1;

            //Creamos la nueva comp con el clip dentro
            var newcomp=app.project.items.addComp(nombre, width, height, par, original.duration, fps);
            var newlayer=newcomp.layers.add(original, original.duration);
            newcomp.parentFolder=tempFolder;

            //Si la escala no es 100, usamos la de la comp original
            if ((layer.scale.value[0] != 100) || (layer.scale.value[1] != 100)) {
                newlayer.scale = layer.scale.value;
                }

            var denoise = newlayer.property("Effects").addProperty(nombreDelPlugin);

            //Añadimos al render queue, y establecemos la ruta de salida
            var rqi = app.project.renderQueue.items.add(newcomp);
            var om = rqi.outputModule(1);                               // Assumes at least one output module
            om.file=new File(rutaRender + "/" + original.name);
            }
        }
    }



function esFootage(lay) {
    if (lay.source instanceof FootageItem) {
        //alert(lay.name + " es footage");
        if (lay.source.mainSource instanceof SolidSource) { return false; }
        else { return true; }
        }
    if (lay.source instanceof CompItem) {
        return true;
        }
    else { return false; }
    }


function inArray(v, arr) {
    for (i=0; i < arr.length; i++) {
        if (arr[i] == v) { return i; }
        }
    return -1;
    }
1

There are 1 best solutions below

0
On

This works fine for me:

var selectedLayers = [
  {hasVideo: true, enabled: true},
  {hasVideo: true, enabled: true},
  {hasVideo: true, enabled: false},
  {hasVideo: true, enabled: true},
  {hasVideo: false, enabled: true}
];

for (var i=0; i < selectedLayers.length; i++) {
  var layer = selectedLayers[i];

  if (!layer.hasVideo || !layer.enabled) {
    //Go for the next one
    continue;
  }

  //Do stuff
  console.log(i);
}

It skips 2 and 4 and outputs:

0 
1 
3 


If you have a loop within a loop it could be that the inner i is being reset, which in that case you'd have to define it outside of the loops.