1

Good time of day! I recently started learning JavaScript and I'm having some difficulty with asynchronous requests. I have to do a lot of requests to the server in as a short time as possible.

for (i=0;i<10;i++;) {
    method.call(get, data: "id", function(result) {
        id = id.concat(data.id);
    })
}

I think my way is incorrect since the request can not be processed in time and has the risk of not getting part of the information.

If you understand what I mean, is there a universal method that is used in such cases and are there any links to articles where all details of working with asynchrony and emerging issues are explained? Sorry for the long question.

3
  • are you using a library for the ajax calls? Commented Mar 10, 2014 at 20:44
  • Are there really 10 independent asynchronous calls or are some dependent on a previous call finishing first? Commented Mar 10, 2014 at 20:45
  • method.call(get, data: "id", function(result) { id = id.concat(data.id); }) this is not valid js syntax Commented Mar 10, 2014 at 20:46

4 Answers 4

2

If timing doesn't matter, you want to use a concept called promises. http://www.promisejs.org/intro/ and http://blogs.msdn.com/b/ie/archive/2011/09/11/asynchronous-programming-in-javascript-with-promises.aspx are good intros. In pseudo code:

when(somethinghappens).then(dosomething)

You can set 10 of those to execute and they will not block each other, presuming the browser allows that many connections.

If timing matters (B can't happen until A is completed) then you want to use callbacks.

getstuff(thingA, function(){
    // do stuff with thingA and then:
    getStuff(thingB, function(){
        // do stuff with thingB and then:
        getStfuff(thingC, function
           // and so on
       }
    }
}

Of course, callbacks don't need to be a nested hell of anonymous function calls. You can name each and do the next call back within the function.

getstuff(thingA, doCallBackB);

function doCallBackB (stuffFromThingA) {
    // do stuff with stuffFromThingA and then
    getstuff(thingB, doCallBackC);
}

More on Callbacks:

  1. https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests
  2. http://recurial.com/programming/understanding-callback-functions-in-javascript/
  3. http://javascriptissexy.com/understand-javascript-callback-functions-and-use-them/
Sign up to request clarification or add additional context in comments.

Comments

1

This code will provide some kind of async recursive loop:

function getId(i) {
    method.call(get, data: "id", function(result) {
        id = id.concat(data.id);

        if (i < 10) {
            i++;
            getId(i);
        }
    });
}

var id = "";
getId(0);

You pass the counter i on each call and check if its reached the limit before call getId another time. So that way the loop will only iterate to next step after each request callback.

Its a kind of pseudo-code, I didn't tested but this is the logic.

Comments

1

I came up with this solution, with a logic seperated approach. I call it async loop, the asyncLoop function here is the main part which is completely general but to use it you should create a function with a specific signature (for the logic code), a function with only one single argument as a callback:

var id="";
function getId(callback){
    method.call(get, {data: "id"}, function(result) {
        id = id.concat(data.id);
        callback();
    });
}

function asyncLoop(i, len, asyncCall) {
    if(i < len){
        asyncCall(function(){
              asyncLoop(i++, len, asyncCall);
        });
    }
}

asyncLoop(0, 10, getId);

The point is, this is not the only way to do this, but what I like about this solution is its general view.

Comments

1

A nice technology for dealing with this kind of asynchronous looping is called continuation programming style (CPS). CPS is closely related to a technology called coroutines. The answer by Will suggests using callbacks, and that is closely related to how CPS is implemented in JavaScript. There are many articles on implementing CPS in JavaScript; here are a few good ones:

The basic idea of CPS is to apply two ideas:

  1. Never return a value from a function; instead write the function to take another function (the continuation) as an extra argument and at the place where a value would be returned, instead call the continuation, passing the return value as an argument.
  2. Whenever function A calls another function B, that's the last thing that A does. If more work is needed, pass a continuation to B that encapsulates the remaining work. When B is done it will call the continuation and the work will then get done.

Sometimes one more idea is added when implementing CPS in JavaScript: use setTimeout() to call the continuation; this avoids stack overflow due to excessive layers of function calls. (Other approaches are also possible to deal with this issue.) The above articles (and many more that you can find with a simple search) elaborate the above ideas and provide lots of examples, including asynchronous looping, AJAX, and many other applications.

1 Comment

+1 had never heard of it as CPS. Very cool. This is probably what happens when one learns programming via as needed google search. :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.