开发者

One of my JavaScript variables seem to be getting reset after a jQuery call

My code sends requests to Twitter for search data gets responses in the from of JSON. After getting the JSON, it stores the count of responses that match a certain condition in an array.

Here is the code that makes the call to the function that queries Twitter.

$(document).ready(function() {
...
graph = new HighCharts.chart({
    chart: {
        events: {
            load: function() {
                console.log("events.load");

                var that = this;
                var update = function() {
                if (polling) {
                    console.log("update()");
                    // The least index series will be nearest the x-axis
                    var stackNumber = 0;
                    var numTweets = updateValues();
                    console.log(numTweets + "");
                    for (var i = 0, currentSeries = that.series; i < currentSeries.length; i++) {
                        var x = (new Date()).getTime(), // current time
                        y = numTweets[i];

                        stackNumber += y;
                        currentSeries[i].addPoint([x, y], true, true);
                    }
               }
          }
          // set up the updating of the chart each second
          var series = this.series[0];
          setInterval(update, 1000);
     }
}

(I'm probably missing some brace somewhere in the code-paste here, but I know for sure that my problem isn't related to a missing brace)

And here is the function that actually queries Twitter using a series of jQuery calls. The updateValues() function (which is outside the document-ready section) goes as follows:

    function updateValues() {
        var url = "http://search.twitter.com/search.json?callback=?&q=";
        var cls = "Penn_CIS240"
        var query = "%23" + cls;
        var voteCount = [0,0,0,0];

        // create an array of zeros
        //for (var i = 0; i < 4; i++)
        //    voteCount.push(0);

        $.getJSON(url + query, function(json){
            console.log(json);
            $.each(json.results, function(i, tweet) {
                var user = tweet.from_user_id;

                if (user % 2 == 0) {
                    voteCount[0] += 1;
                }
                else if (user % 3 == 0) {
                    voteCount[1] += 1;
                }
                else if (user % 5 == 0) {
                    voteCount[2] += 1;
                }
                else {
                    voteCount[3] += 1;
                }
                console.log("updateValues() -> getJSON -> each -> voteCount = " + voteCount);
            });
            console.log("updateValues() -> getJSON -> voteCount = " + voteCount);
        });
        console.log("updateValues() -> voteCount = " + voteCount);

        return voteCount;
    }

What is happening is that the variable voteCount is getting incremented properly inside the jQuery calls. However, outside of the calls, it is getting reset. So the log outputs look something like this:

updateValues()开发者_运维技巧 -> getJSON -> each -> voteCount = [1,0,0,0]
updateValues() -> getJSON -> voteCount = [1,0,0,0]
updateValues() -> voteCount = [0,0,0,0]

Does this problem have to do with jQuery's asynchronous calls, and I'm having interesting variable modification conflicts? Or is it something else?


When you use asynchronous callbacks in JavaScript, they execute later... asynchronously. So if you have:

var x = 5;
console.log("before getJSON", 5);
$.getJSON("/some/url", function (json) {
    x = 10;
    console.log("inside callback", x);
});
console.log("after getJSON", x);

the output will be

before getJSON 5
after getJSON 5
inside callback 10

Any code you want to execute after the request returns must be inside the callback; putting it physically "after" the $.getJSON call will not suffice. You should think of $.getJSON as "firing off" the JSON-getting process, then immediately returning to you; only later, when your script is done executing normal code and the server has responded, will the JavaScript event loop say "hey I got a response and am idle; time to call that callback that was waiting on the response!"


Because of this, your updateValues function will need to accept a callback of its own in order to notify its own caller that the values have been updated; just calling updateValues will only fire off the value-updating process, and the values won't be updated later until that idle time. Something like:

function updateValues(onUpdated) {
    var url = "http://search.twitter.com/search.json?callback=?&q=";
    var cls = "Penn_CIS240"
    var query = "%23" + cls;
    var voteCount = [0,0,0,0];

    $.getJSON(url + query, function (json) {
        // use of json to update voteCount ellided

        onUpdated(voteCount);
    });
}

Then calling code uses it as

updateValues(function (voteCount) {
    // use the updated vote counts inside here.
});
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜