JavaScript Javascript breaking a for loop inside a callback function

I have code like the following:

function test(obj) {

    if(//some conditon) {
        obj.onload();
    }else{
        obj.onerror();
    }
}


for(var i=0;i<4;i++){   

    test({
        onload:function(e){          
            //some code to run
        },
        onerror:function(e){
            break;
        }


    });
}

The gist is the test() function is a function to make an XHR request (it is actually an API of the Appcelerator Titanium platform so I have no control over it) and I'm looping something to call the test function. I need to break the loop on the onerror function, but I get an error saying the break is not inside a loop or switch statement. How can I rewrite this?

Answer:1

If your code sample does represent some actual code (i.e. all the processing is done in the same event loop tick), you may do the following:

function test(obj) {

    if (some_condition) {
        return obj.onload();
    } else {
        return obj.onerror();
    }
}

var result;
for(var i=0; i<4; i++){   

    result = test({
        onload:function(e){          
            //some code to run
            return true;
        },
        onerror:function(e){
            return false;
        }


    });

    if (!result) {
        break;
    }
}

Otherwise, if there is something asynchronous done, you have to call test sequentially, and not in parallel. For example,

function test(obj) {
    doSomeAjaxRequest(arguments, function (err, result) {
        if (some_condition) {
            obj.onload();
        } else {
            obj.onerror();
        }
    });
}

var f = function (i) {
    if (i >= 4) return;
    test({
        onload:function(e){          
            //some code to run
            f(i+1);
        },
        onerror:function(e){
            break;
        }
    });
}

f(0);
Answer:2

Not possible. A for loop is a synchronous procedure while an Ajax request is not. That means when the onerror callback happens, the for loop is already done executing.

As an alternative you could introduce a check into your onsuccess handler which confirms no errors have happened yet.

var errorOccured = false;
for(var i=0;i<4;i++){   

test({
    onload:function(e){   
        if(errorOccured) return;
        //some code to run
    },
    onerror:function(e){
        errorOccured = true;
    }


});
}
Answer:3

Bit hacky maybe but one could do something like this with a handler function.

var handler = function(array, callback){
    for(var i=0, l=array.length, e=array[i]; i<l; ++i){
        if(true === handler.exit){
            handler.exit = false; //restore
            return;
        }
        callback.call(null, e);
    }
};
handler.exit = false; 

handler([1,2,3], function(e){
   console.log(e);
   if(2 === e){
       arguments.callee.caller.exit = true; // :-)
   }
});

Didn't test this but maybe you could bind function to scope in call even?

var handler = function(a, f){
    this.exit = false;
    for(var i=0, l=a.length, e=a[i]; i<l; ++i){
        if(true === this.exit){
            this.exit = false; //restore
            return;
        }
        callback.call(this, e);
    }
};
handler([1,2,3], function(e){
   console.log(e);
   if(2 === e){
       this.exit = true;
   }
});
Answer:4

You cannot break the loop inside test() function. I think the best solution in this case would be to throw an exception inside test() function, then catch it in the loop and break.

Answer:5

Maybe you can make the 'onload' callback recursive?

Meaning, you just call the 'test' method inside the 'onload' handlerr, this would also mean you fire all requests in order instead of all at the same time.

Answer:6

In Three.js, I would like to use THREE.quaternion to make the camera object rotate to the selected object. I did search the web but found no example/demo or document about how to use this quaternion ...

In Three.js, I would like to use THREE.quaternion to make the camera object rotate to the selected object. I did search the web but found no example/demo or document about how to use this quaternion ...

  1. three.js rotate camera quaternion
  2. three js camera quaternion
  3. three.js rotate object quaternion

I am creating a popup window that goes to hello.html. I want my original (parent page) to reload when i close the popup window (hello.html). I can't seem to get it to work, but I'm close. Here is ...

I am creating a popup window that goes to hello.html. I want my original (parent page) to reload when i close the popup window (hello.html). I can't seem to get it to work, but I'm close. Here is ...

  1. refresh parent window after closing modal dialog
  2. refresh parent window after closing popup
  3. reload parent window after closing popup
  4. javascript refresh parent window after closing popup
  5. auto refresh parent window after closing popup javascript
  6. refresh parent window after closing child window javascript
  7. refresh parent page after closing popup window
  8. refresh parent page after closing modal dialog

In the IE developer (F12) console, I've managed to get my pages to run without errors; all but one! SCRIPT1002: Syntax error mypage.php, line 1 character 6 I am using IE9. Whats it's problem? ...

In the IE developer (F12) console, I've managed to get my pages to run without errors; all but one! SCRIPT1002: Syntax error mypage.php, line 1 character 6 I am using IE9. Whats it's problem? ...

  1. script1002 syntax error line 1 character 1

I have several images positioned on top of each other using absolute positioning. These images are partially transparent, and have a html area and map to make only the visible parts clickable. In ...

I have several images positioned on top of each other using absolute positioning. These images are partially transparent, and have a html area and map to make only the visible parts clickable. In ...