0

How can we make the asynchronous function stop and wait for the response? I got some solution about getting the value from asynchronous functions from How do I return the response from an asynchronous call? But, I still have more questions about how can we get a value from asynchronous function if we have to pass in some values to the function.

Here, I have 3 functions. First, the asynchronous function.

 function getVal(param,callbackFunc)
 {
     a = function()
     {
       if(a.state==finished)
             callbackFunc(a.response);
     };
 }

This one is the call back function

 handler(result)
 {
    return result;
 }

And, This is where I call the asynchronous function, and also where I got the problem

function core()
{
  for(var i = 0 ; i < 10 ; i ++)
  {
    getVal(g[i],handler);
  }
}

As you can see, the parameter I sent to the getVal function is an array. So, the question is how can we make the getVal function execute the parameters synchronously.

This always give me the result of the last member of array (It seems like the function skips all values from g[0] to g[9].it always returns the value of getVal(g[10],handler)) .

Please help

Thank you.

Community
  • 1
  • 1
user3505908
  • 5
  • 1
  • 7
  • I feel like there is missing some important stuff in your script so that we can understand your problem, but i guess that the solution you're looking for is http://stackoverflow.com/a/1676422/3820185 – wiesion Sep 13 '15 at 12:19
  • Well, if you read the question you linked to carefully you see that **you can't** return the response from an asynchronous call. This is **an inherent part of the concurrency model**. You can only return a promise or take a callback. If you use ES2016 async/await syntax you can get close, generators are also nice, but that's about it. – Benjamin Gruenbaum Sep 13 '15 at 12:23
  • What if I separate the asynchronous function to a class, and call an instance instead of calling the function directly? – user3505908 Sep 13 '15 at 12:28
  • You are asking the equivalent of "get me a person who breaks the law all the time but isn't a criminal". Not waiting for the return value is part of the *definition* of asynchronous. – Jared Smith Sep 13 '15 at 12:30
  • 1
    @JaredSmith: the answer to that is "a politician". – Andy Sep 13 '15 at 12:41
  • @Andy lol I should have thought of an analogy with a less hilarious counterexample. – Jared Smith Sep 13 '15 at 12:47

2 Answers2

0

Your problem is not directly related to Ajax, it occurs whenever the execution of a code block is delayed. The following code snippets reproduce this situation using a timer. The last code snippet is a possible solution to your problem. By the way, if you still feel confused about Ajax, here is an attempt to make it easy to understand: https://stackoverflow.com/a/32163917/1636522.


No delay: i is printed immediately.

print('loop start');
for (var i = 0; i < 3; i++) {
  print(i);
}
print('loop end');

function print (html) {
  document.body.innerHTML += html + '<br />';
}

1 second delay: The print action is executed 1 second later, but the "for" loop keeps going, hence, i reaches 3 before being printed.

print('loop start');
for (var i = 0; i < 3; i++) {
  setTimeout(function () {
    print(i);
  }, 1000);
}
print('loop end');

function print (html) {
  document.body.innerHTML += html + '<br />';
}

1 second delay + persistence: i is copied to a new variable. This variable is local to the self-invoking function and still alive when the print function is called.

print('loop start');
for (var i = 0; i < 3; i++) {
  (function (copy) {
    setTimeout(function () {
      print(copy);
    }, 1000);
  })(i);
}
print('loop end');

function print (html) {
  document.body.innerHTML += html + '<br />';
}
Community
  • 1
  • 1
-1

One way to do that is by making ajax request synchorous.

var xhr =new XMLHttpRequest();
xhr.open("GET","url", false);

False here will make sure rest of the code isnt ran until havent gotten response.

Otherwise what i do is make all async requests then upon every response subtract 1 from array.length and check if it's zero. If it is then it means we have gotten all of the responses so then call the callback.

Muhammad Umer
  • 17,263
  • 19
  • 97
  • 168
  • Got warning after tried your solution!!! "Synchronous XMLHttpRequest on the main thread is deprecated because of its detrimental effects to the end user's experience. For more help, check http://xhr.spec.whatwg.org/." – user3505908 Sep 13 '15 at 16:37
  • Yes it's saying it's not a good practice. So for which reasons i also think you are better off creating a variable, say Left, then make it equal to length of array. And then each time you get response minus 1 from it. And upon every response also check if it's Left==0 then if it's then you know you are all done – Muhammad Umer Sep 13 '15 at 16:46