Communiquez avec les autres et partagez vos connaissances professionnelles

Inscrivez-vous ou connectez-vous pour rejoindre votre communauté professionnelle.

Suivre

Does anybody know why I am facing this problem?

The below script should send 3 requests to the server, and then print a message after its done with each request:

 

call #0 finished

call #1 finished

call #2 finished

 

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

    $.post( "https://gurujsonrpc.appspot.com/guru", function(d) {

          console.log( "call #" + i + " finished" );

    });

}

 

But after running it, it prints the below:

 

call #3 finished

call #3 finished

call #3 finished

 

Why did this happen? what should I do to solve it?

user-image
Question ajoutée par Samar Saleh , Community Manager , Bayt.com
Date de publication: 2017/01/22
Utilisateur supprimé
par Utilisateur supprimé

Because JavaScript is Asynchronous you cannot guarantee the order which the log entries appear but you will get the correct entries if you use the following code:

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

      handlePost( i );

  

  }

  

  function handlePost ( i ) {

    $.post ( "https://gurujsonrpc.appspot.com/guru", function(d) {

          console.log( "call #" + i + " finished" );

    });

  }

With you example, i is getting set in the for loop and post calls only complete after the for loop has completed. This means that the value of i is always 3. This code takes the current value of i and keeps it. I would recommend reading about closure and scope in javascriptSee working example here https://plnkr.co/edit/9O5WJuZFClMe8p0w9sz0

Hazem Qannash
par Hazem Qannash , Technical Team Leader , Bayt.com

Martin Paul Lippert's answer is correct, the $.post is asynchronous, so the callback function will be executed after done with the for, and it will use the same scope for, so the value of "i" will be3 always.

You can simply, create a new scope for the $.post as below:

 

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

  (function(i){

    $.post( "https://gurujsonrpc.appspot.com/guru", function(d) {

          console.log( "call #" + i + " finished" );

    });

  })(i);

}

 

And the result will be something like:

call #1 finished

call #2 finished

call #0 finished

Atif Majid
par Atif Majid , Senior PHP Programer/Team Lead , RedApple Apartments AB

Hi

When you get the response back, the value of i has already been set to 3. That's why you get 3 all the time.

 

Can you try this. This worked for me

 

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

                $.ajax({

                    url: "https://gurujsonrpc.appspot.com/guru",

                    indexValue: i,

                    success: function(data) {

                        console.log( "call #" + this.indexValue + " finished" );

                    }

                });

            }

bassem Khabiry
par bassem Khabiry , programmer , Access Tier LLC

the code is right but the Post method by default in JS is Asynchronized(No order) which mean it will not wait for respond back from the server before it move to next LOC and here the problem start, the post method inside the for loop will execute and send a request to a server 3 times and after each time it will jump and increase i+1, and after 3rd time it stops cause of the loop condition. and to be able to solve this issue you need to follow one of these step:

1) modify the code 

move the  " console.log ( "call #" + i + " finished" ); "

to be outside the Post function and inside the for loop.

and in this case it will print after the method finish executing.

OR

2)Change the Post method to be Synchronized by using a help with Ajax:

code start:

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

$.ajax (

{

url : " https://gurujsonrpc.appspot.com/guru"

type: "POST",

data: data,

async: false, 

     success: function(d) 

          console.log ( "call #" + i + " finished" );

    });

code ends.

and in this case when the post method get call, the code will wait tel it finish executing then move to the next step"In Order".

Jonathan de Flaugergues
par Jonathan de Flaugergues , software engineer , Abbeal

Because, the callback of your ajax request is executed after your for loop.

To get the value of the i variable, you have to pass it to the callback.

The best way to do this is to bind your callback function with your i variable. And access it with the keyword this inside your callback.

 

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

    $.post( "https://gurujsonrpc.appspot.com/guru", function(d) {

          console.log( "call #" + this + " finished" );

    }.bind(i));

}

 

Add a console.log after your loop and you'll see that it's executed before the3 callbacks.

Utilisateur supprimé
par Utilisateur supprimé

for ( var i=0;i<3;i++)

{ x += "Call #" + i + "Finished" ; } $.post ( "https://gurujsonrpc.appspot.com/guru", function(d) { console.log(x);} );

Utilisateur supprimé
par Utilisateur supprimé

I think you have good answers for the question already. The answer of  Martin Paul Lippert Hazem QannashAtif Majid and Jonathan de Flaugergues are excellent.

The problem with your $.post calls is they are bound to the variable i which is outside of the function. The for loop runs much faster than the post is returned and of course the var i is used in the function by reference. It's not a copy of the var i.

So, both Hazem Qannash's answer (based on Martin's) and Jonathan de Flaugergues' will work correctly. Hazem's solution is excellent but more difficult to read and easy to miss the parenthesis, and of course, will be difficult to maintain. This is why I'd prefer Jonathan's.

 

Suraj Abraham
par Suraj Abraham , GM - Sales & Marketing , Kora Trading & Contracting Co., Doha, Qatar

I will go with the opinion of Mr.Martin Paul Lippert. He is right.

Rojbeni Lokmen
par Rojbeni Lokmen , IT Consultant , faculty (fsegt)

Load data from the server using a HTTP POST request normally like this , but you have  to be attentive to asynchronous JSquery :

//  create function (javascript) and callback in  the  loop Code goes here  ...

$(document).ready(function ()

{

        

     function POSTJSQFUN((i)

    {

    $.post( "https://gurujsonrpc.appspot.com/guru", function(d) {

 

         console.log( "call #" + i + " finished" );

 

    });

    }

        for ( var i=0; i<3; i++)

       {

      POSTJSQFUN(i);

       }

 

});

Manzoor Alam
par Manzoor Alam , Director , 7th Sky Travel & Tourism Services (Pvt.) Limited

I would prefer to go with the experts views....

هاشم المشارقة
par هاشم المشارقة , Key Account Manager , Advanced United Systems Ltd. ( A member of Taj Holding Group)

I review the code but unfortunately I could not find any mistake but please tell us about the function(d) 

what does it do ?

More Questions Like This