</div>
</div>
<div class="grid--cell mb0 mt4">
<a href="/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call" dir="ltr">How do I return the response from an asynchronous call?</a>
<span class="question-originals-answer-count">
(38 answers)
</span>
</div>
<div class="grid--cell mb0 mt8">Closed <span title="2013-09-10 06:44:26Z" class="relativetime">6 years ago</span>.</div>
</div>
</aside>
This seems like a ridiculously trivial issue but I can't solve it.
I have this function. var q
is assigned to an array of strings. alert(q)
successfully prints the entire array when the function is called.
function initQuestions() {
$.post("quiz.php", { 'func': 'load' }, function(data) {
var q = data.split(".
");
alert(q);
return q;
});
}
However, when I attempt to use the function (as depicted below in 2 ways) I am told the array is undefined. Why is this the case?
var questions;
$(function() {
//This doesn't work
questions = initQuestions();
alert(questions);
//Neither does this
alert(initQuestions());
});
Upon further research I added a callback to initQuestions()
but am having the same result.
</div>
The post call is asynchronous: Async Javascript
Basically, the initQuestions() function returns null
before the post
finishes
Thinks of it like this:
function initQuestions() {
$.post("quiz.php", { 'func': 'load' }, function(data) {
var q = data.split(".
");
alert(q);
return q; // <- returns to the caller of function(data), not initQuestions()!
});
return null; // <- This happens before function(data) is complete
}
To make it work as expected, you need to supply a callback for when the post is successful and finishes.
function initQuestions(callback) {
$.post("quiz.php", { 'func': 'load' }, function(data) {
var q = data.split(".
");
alert(q);
callback(q);
});
}
var questions;
function doSomthingWithQuestions() {
alert(questions); // <- should work
// do the things with the questions
}
$(function() {
initQuestions(function(result) {
questions = result;
doSomethingWithQuestions();
});
// Don't use `questions` here as the callback hasn't fired yet.
});
The post is asynchronous, return doesnt go to the function you expect, but to the success handler:
function initQuestions() {
$.post("quiz.php", { 'func': 'load' }, function(data) { // <- this function has that return
var q = data.split(".
");
alert(q);
return q;
});
}
here is how to supress asynchronous behaviour and achive what you want
EDIT:
As some people said here, asych = false
is a bad idea since it freezes you JS code until the request is done (can take seconds with slow connection), so solution would be to do whatever you want in the success function:
questions = initQuestions(); //wrong
fillDivsWithData(questions); //use callback instead:
function initQuestions() {
$.post("quiz.php", { 'func': 'load' }, function(data) {
var q = data.split(".
");
console.log(q); //diplay this in you browser's JS console
fillDivsWithData(q);
});
}
result is same, but thanks to asynch request your JS code doesnt freeze for seconds if you have potatoe internet connection.
var questions; // undefined right now
initQuestions(function(_questions){
questions = _questions; // the value has been set thanks to the anonymous function you passed as the callback
})
function initQuestions(callback // this is a callback function reference) {
// This HTTP Post call takes time to complete and is done asynchronously
$.post("quiz.php", { 'func': 'load' }, function(data) {
var q = data.split(".
");
// Luckily your initQuestions now takes in a callback function
// You have access to the callback function here and when ready you can use it
callback(q);
});
// JavaScript engine doesn't wait for your HTTP call to complete
// and will continue to execute the function
// In this case, your function isn't returning anything hence undefined
}