How can I pass data from an ajax request to a glob

2019-08-06 09:41发布

问题:

Ok. I'm totally baffled. Here's the code:

$(document).ready(function(){
var newToken = 1;

$.get("junk.php",
    function(newToken) {
        alert(newToken); // alerts "junk"
    });
alert(newToken); // alerts "1"
});

As per my comments, the first alert of newToken is "junk" (the only output of junk.php). Once outside the .get, newToken reverts to "1". I need to get this variable set to the output from junk.php. Is this not possible? I've tried everything, and searched everywhere.

Thanks.

回答1:

You're shadowing the first newToken variable with a new newToken variable that is used as an argument:

Problem:

$(document).ready(function(){
var newToken = 1; // <== newToken number 1

$.get("junk.php",
    function(newToken) { // <== This is newToken number 2.
                         //     since it's the first argument
                         //     in the get success function it will
                         //     be the data returned.

        alert(newToken); // <== Alerts the data returned. newToken number 1 is 
                         // shadowed, obscured, covered up...
    });
alert(newToken);
});


Work around... use different names, or even the arguments array:

Solution:

$(document).ready(function(){
var newToken = 1;

$.get("junk.php",
    function() {  // <== don't shade newToken
                  //     you could use another variable name like "data"
                  //     but I decided to use the arguments array for kicks

        alert("Data is: " + arguments[0] + // <== junk
              "\nNew Token is: " + newToken); // <== 1
    });
alert(newToken); // alerts "1"
});

Info on $.get()

Note that if you update newToken in the get callback things can get tricky due to the asynchronous nature of the call. Basically, be aware of the fact that everything you write in the callback of $.get() will get executed only when the request is done ( a while later ), but everything after $.get() but within the doc ready will get executed right away, and the get callback will have access to the state of variables as they were when the doc ready function returned................ basically, you can give newToken an initial value and then work with it in the get callback, but anything else might cause results that you don't except.

Some examples:

$(document).ready(function(){
    var newToken = 1;

    $.get("junk.php",
        function() {
            newToken++;
            alert(newToken); // alerts 2, so far so good.
        });
    });

$(document).ready(function(){
    var newToken = 1;

    $.get("junk.php",
        function() {
            newToken++;
            alert("get: " + newToken); // alerts 3 - this is the last alert
        });

    newToken++;
    alert("ready:" + newToken); // alerts 2 - 
                                // this happens before the server responds
});

jsFiddle example



回答2:

$(document).ready(function(){
    var newToken = 1;

    $.get("junk.php",
        function(data) {
            alert(newToken); 
        });
    alert(newToken); // alerts "1"
});


回答3:

First, your definition of newToken is inside the context of that anonymous function passed to $(document).ready(), so it's not global at all. I don't think this is the problem real, though...

More serious is this: The call to $.get is asynchronous, so control passes immediately to your alert(newToken) statement without waiting for the http request to finish, or for its callback to run. So any code relying on data retrieved in that call should run in its callback.



回答4:

I found the answer - of all places on the jQuery website (surprise, surprise), buried in the commentary.

newToken = $.ajax({ type: "GET", url: "junk.php", async: false }).responseText;

This solves the problem - being that it was asynchronous, and that needed to be set to false. This cannot be accomplished using the jQuery.get(), but must be jquery.ajax, where the async:false can be set.

With the request in this format, newToken can be used throughout the script. Hope this ends up helping someone else.