I have a function which declares a variable with the var
keyword. It then launches an AJAX request to set the value of the variable, and this variable is then returned from the function.
However, my implementation fails and I 'don't know why.
Here's a simplified version of the code;
function sendRequest(someargums) {
/* some code */
var the_variable;
/* some code */
request.onreadystat开发者_开发知识库echange =
//here's that other function
function() {
if (request.readyState == 4) {
switch (request.status) {
case 200:
//here the variable should be changed
the_variable = request.responseXML;
/* a lot of code */
//somewhere here the function closes
}
return the_variable;
}
var data = sendRequest(someargums); //and trying to read the data I get the undefined value
AJAX requests are asynchronous. Your sendRuest function is being exectued, the AJAX request is being made but it happens asynchronously; so the remainder of sendRuest is executed, before the AJAX request (and your onreadystatechange handler) is executed, so the_variable
is undefined when it is returned.
Effectively, your code works as follows:
function sendRuest(someargums) {
/* some code */
var the_variable;
/* some code */
return the_variable;
}
var data = sendRequest(someargums);
And then some time later, your AJAX request is completing; but it's already too late
You need to use something called a callback:
Where you previously may have had
function () {
var theResult = sendRuest(args);
// do something;
}
You should do:
function () {
sendRuest(args, function (theResult) {
// do something
});
};
and modify sendRuest
as follows:
function sendRuest(someargums, callback) {
/* some code */
//here's that other function
request.onreadystatechange =
function() {
if (request.readyState == 4) {
switch (request.status) {
case 200:
callback(request.responseXML);
/* a lot of code */
//somewhere here the function closes
}
}
This is not about scope - its about async processing.
The function sendRuest ends before the onreadystatechange function gets called.
You can't return the variable from the function that creates the ajax callback since the variable won't be set yet. The ajax function in turn has to call another callback with the returning result.
request.onreadystatechange =
function() {
if (request.readyState == 4) {
switch (request.status) {
case 200:
//here the variable should be changed
the_variable = request.responseXML;
the_callback(the_variable);
Instead a plain string variable, you can use an object.
function sendRuest(someargums) {
var the_variable = {
data: null,
setData: function(data){ this.data = data;}
}
//here's that other function
request.onreadystatechange =
function() {
if (request.readyState == 4) {
switch (request.status) {
case 200:
//here the variable should be changed
the_variable.setData(request.responseXML);
}
return the_variable;
}
Anyway, your last line isn't going to work. When the function 'sendRuest' ends, the XHR request is not completed. You need to use timers to check the value of 'the_variable.data' (very bad) or use callbacks as stated in other answers.
Sergio.
精彩评论