1

if i call test(3) i'm getting alert with message 1.

function test(param) {

    var tt = [ "a", "b", "c" ];
    for ( var i = 0; i < param; i++) {
        if (tt[i] == "b") {
            test(1);
            alert(i);
        }
    }
}

but it's not working properly in success event. if i call below method test(3) and pls consider it's success from request. i am getting alert with message 3.

function test(param) {

    var tt = [ "a", "b", "c" ];
    for ( var i = 0; i < param; i++) {
        if (tt[i] == "b") {
            Ext.Ajax.request( {
                url : 'test.do',
                method : 'POST',
                success : function(response) {
                    test(1);
                    alert(i);
                }
            });
        }
    }
}
shift66
  • 11,760
  • 13
  • 50
  • 83
  • 1
    may be duplicate of http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – rab Jul 01 '13 at 08:33
  • Thanks for your response rab. but for me first function working correct(which conclude scoping is correct). only issue if I used 'i' in events. – Muthuramu Periyaiah Jul 01 '13 at 08:43

2 Answers2

3

You need to put i in a closure around your asynchronous function call. You can realize this by using an IIFE, that creates a scope inside the for-loop, in which the value of i is preserved:

for ( var i = 0; i < param; i++) {
    if (tt[i] == "b") {
        (function(i){
            Ext.Ajax.request( {
                url : 'test.do',
                method : 'POST',
                success : function(response) {
                    test(1);
                    alert(i);
                }
            });
        }(i));
    }
}

But it looks like, you only need i for the alert-message which is probably for debugging purposes only. So if everything else works fine and you don't really need to access i inside of the callback function (success), then you also don't need the additional scope.

basilikum
  • 10,378
  • 5
  • 45
  • 58
  • Thanks Basilikum. I not worried about alert. I'm working on creating dynamic components for form. In that form i got fieldset(again it contain dynamic components). That's why i need recursive function. In success event ill get components for fieldset. that coding is too big, that is why i put sample question. – Muthuramu Periyaiah Jul 01 '13 at 09:46
  • 1
    @basilikum is there a good article on this subject? I'm interested at how these scopes work – casraf Jul 01 '13 at 09:49
  • 1
    @ChenAsraf you only have to understand that the only expression that creates a new scope in javascript is a function. In my example it is just a function that calls itself immediately and passes the current value of `i` to itself, so that in a new variable `i` is defined inside the function body. I'm not really sure about articles. Just google "javascript function scope" or "javascript IIFE" if you are particulary interested in these types of function. Nonetheless, here is one article that I quickly found, that might be interesting for you: http://tinyurl.com/2gxrzdh – basilikum Jul 01 '13 at 09:59
0

Ok, that's your code: http://jsfiddle.net/848AE/1/

Look in console (i change success event to failure, but it doesn't matter).

function test(param) {
    console.log('------------------------------');
    console.log('param = ' + param);
    var tt = [ "a", "b", "c" ];
    for ( var i = 0; i < param; i++) {
        console.log('Before if-check, i = ' + i);
        if (tt[i] == "b") {
            console.log('Request start, after if-check i = ' + i);
            Ext.Ajax.request( {
                url : 'test.do',
                method : 'POST',
                failure: function(response) {
                    console.log('Failure start, i = ' + i);
                    test(1);
                    console.log('Alert(i) = ' + i);
                }
            });
            // break; 
        }
    }
}

test(3);

Log from first code (without break word in cycle):

------------------------------
param = 3
Before if-check, i = 0 
Before if-check, i = 1
Request start, after if-check i = 1
Before if-check, i = 2
POST http://fiddle.jshell.net/_display/test.do 404 (NOT FOUND) ext-all.js:21
Failure start, i = 3
------------------------------
param = 1
Before if-check, i = 0
Alert(i) = 3

As you can see, when you start request, function didn't stop to execute and continue to work in cycle (i = 2, 3). So, when you get response from server, variable i has value 3.

Then, you call function with argument 1, it's finish and go back to failure function, but in failure function scope the variable i still has a value 3.

So, if i understand you right, you have to add break word in cycle as in code comment.

Edit:

If do you like to execute requests in cycle with pausing until callback executed, there is not documented property:

var response = Ext.Ajax.request({
    ...
    async: false,
    ...
})

Result with async:false :

param = 3 
Before if-check, i = 0
Before if-check, i = 1
Request start, after if-check i = 1
POST http://fiddle.jshell.net/_display/test.do 404 (NOT FOUND) ext-all.js:21
Failure start, i = 1
------------------------------ 
param = 1 
Before if-check, i = 0
Alert(i) = 1
Before if-check, i = 2 
Maxim Zhukov
  • 10,060
  • 5
  • 44
  • 88