0

This is the code that is working but not the way i need it too, ill explain it after.

getRegisterFiles('regster1')
function getRegisterFiles(name) {
    var request = $.ajax({
        url: "/../files/Users/"+name+".ctp",
        type: "GET",
        dataType: "html"
    });
    request.fail(function(jqXHR, textStatus) {
        $('#pageLoading p').html('We have experienced a problem. Please try again later.');
        return false;
    });
    request.success(function(msg) {
        placeData(msg);
    });
}
function placeData(registerData) {
    $('#pageWrap').html(registerData);                      
}

So the code above gets a .ctp file and then displays it on screen.

What i need it to do

Instead of having the placeData(msg) in the success part i want to return the contents of 'msg' to a variable that will initiate the function like so,

register = getRegisterFiles('register1');

I have tried using,

return msg;

but it doesn't work... If i use return msg and then 'alert' it it comes up as undefined.

I have no idea what todo next so any ideas will be greatly welcomed. Sorry if its a complete newb mistake.

EDIT --- This is the code i have tried, i hope it helps to show you what i'm trying to do.

var registerStep1 = null;
var registerStep2 = null;
function getRegisterFiles(name) {
    var request = $.ajax({
        url: "/../files/Users/"+name+".ctp",
        type: "GET",
        dataType: "html",
        error: function(jqXHR, textStatus) {
            $('#pageLoading p').html('We have experienced a problem. Please try again later.');
            return false;
        },
        success: function(msg) {
                return msg;
        }
    });
}
registerStep1 = getRegisterFiles('registerStep1');
registerStep2 = getRegisterFiles('registerStep2');
var tempInterval = setInterval(function() {

    if(registerStep1 != null && registerStep1 != false) {
        if(registerStep2 != null && registerStep2 != false) {
            clearInterval(tempInterval);
            placeData(registerStep1);
        }
    }
}, 100);
function placeData(registerData) {
    var tempTimer = 0;
    tempTimer = setInterval(function() {
        if(controlTimeUp != false) {
            $('#pageWrap').html(registerData);
            methodToFixLayout();
            $('#pageWrap').fadeIn("slow");
            $('#pageLoading').css("display","none")
            clearInterval(tempTimer);
        }
    }, 10)
}
4

2 回答 2

2

You're doing it correctly. An AJAX call can not return a value to the caller. This is due to AJAX being Asynchronous. (This is what the first 'A' in AJAX stands for). The call to getRegisterFiles('register1') returns immediately. It does not block and wait for the response from the server. Thus it can't return any value that relates to the response from the server.

Here is another StackOverflow question pertaining to the asynchronous nature of AJAX requests: Are AJAX calls not blocking and what is their lifespan?

Updated to add more explanation:

To observe these examples, install the FireBug extension for Firefox or use Chrome. Open FireBug or the Developer Tools, respectively, and watch the console tab.

Here I took your code and added many log messages to reveal the order in which execution occurs.

console.log('Defining function getRegisterFiles()');
function getRegisterFiles(name) {
    console.log('enter: getRegisterFiles()');
    var request = $.ajax({
        url: "/../files/Users/"+name+".ctp",
        type: "GET",
        dataType: "html"
    });
    console.log("configuring failure handler");
    request.fail(function(jqXHR, textStatus) {
        console.log('enter: failure callback function');
        $('#pageLoading p').html('We have experienced a problem. Please try again later.');
        console.log('exiting: failure callback function');
        return false;
    });
    console.log("configuring success handler");
    request.success(function(msg) {
        console.log('enter: success callback function');
        placeData(msg);
        console.log('exiting: success callback function');
        return msg;
    });
    console.log('exiting: getRegisterFiles()');
    return "This is the return value of getRegisterFiles()";
}

console.log("defining placeData() function');
function placeData(registerData) {
    console.log('enter: placeData();  registerData="+registerData);
    $('#pageWrap').html(registerData);
    console.log('exiting: placeData()');
}

console.log("calling getRegisterFiles()');

var result = getRegisterFiles('regster1')
console.log("getRegisterFiles() finished;  result="+result);

The sequence of log messages should make the order of execution more clear. When you call getRegisterFiles() you configure some parameters and initiate a request. The function then returns. You don't have any response from the server yet, so you can't act on it yet. This is visible in the log message that contains "getRegisterFiles() finished". Some time later a response is received from the server. At this time, jQuery calls the function you registered as the success handler. Although you technically can return a value from the function, since jQuery called it the return value is returned to jQuery where it is simply ignored.

Here is another variation where, as per your comment, assignment is used:

var dataFromTheServer = "An initial value";

console.log('Defining function getRegisterFiles()');
function getRegisterFiles(name) {
    console.log('enter: getRegisterFiles()');
    var request = $.ajax({
        url: "/../files/Users/"+name+".ctp",
        type: "GET",
        dataType: "html"
    });
    console.log("configuring failure handler");
    request.fail(function(jqXHR, textStatus) {
        console.log('enter: failure callback function');
        $('#pageLoading p').html('We have experienced a problem. Please try again later.');
        console.log('exiting: failure callback function');
        return false;
    });
    console.log("configuring success handler");
    request.success(function(msg) {
        console.log('enter: success callback function');
        dataFromTheServer = msg;
        console.log('exiting: success callback function');
    });
    console.log('exiting: getRegisterFiles()');
    return "This is the return value of getRegisterFiles()";
}

console.log("defining placeData() function');
function placeData(registerData) {
    console.log('enter: placeData();  registerData="+registerData);
    $('#pageWrap').html(registerData);
    console.log('exiting: placeData()');
}

console.log("calling getRegisterFiles()');

getRegisterFiles('regster1')
console.log("getRegisterFiles() finished;  dataFromTheServer="+dataFromTheServer);
placeData(dataFromTheServer);

The reason this does not work as intended is because placeData() is called (long) before the server responds to the request and so the assignment has not yet occured. Eventually, when the response is received, the assignment does occur but since no functions are called at that time, nothing is done with that value.

Additionally, I would advise against using the assignment to a global name technique. Using local variables is easier to debug, easier to verify correctness, and easier to reuse the code as the software project is modified to meet changing needs than using global variables.

于 2012-07-31T22:56:22.723 回答
0

Where are you trying the return? It has to be in scope:

request.success(function(msg) {
    placeData(msg);
    return msg;
});

Should work, if it is outside of there, it is undefined.

Second, if that does not, I don't know if you are using another plugin, but maybe you should handle your success/failure like this?

function getRegisterFiles(name) {
    var request = $.ajax({
        url: "/../files/Users/"+name+".ctp",
        type: "GET",
        dataType: "html",
        error: function(jqXHR, textStatus) {
            $('#pageLoading p').html('We have experienced a problem. Please try again later.');
            return false;
        },
        success: function(msg) {
            return msg;
        }
    });
}

That is how it is defined here: http://api.jquery.com/jQuery.ajax/

于 2012-07-31T19:42:56.910 回答