How can I use AJAX to fetch data and store it in javascript variables?

会有一股神秘感。 提交于 2019-12-12 19:32:05

问题


This is a sample dynamically updated chart: http://www.highcharts.com/demo/dynamic-update

The chart is updated every second with the the date as the x value and a random number as the y value.

load: function() {            
    // set up the updating of the chart each second
    var series = this.series[0];
    setInterval(function() {
        var x = (new Date()).getTime(), // current time
            y = Math.random();
        series.addPoint([x, y], true, true);
    }, 1000);
}

How would I rewrite load to fetch x and y from another webpage using AJAX, rather than generating the values within the function?


回答1:


I take it what you want is the sample load method but with the lines that set x and y replaced with an AJAX call. You'll need to perform a fairly basic continuation-passing code transformation, turning the code after the point you want the asynchronous call into a function that's passed to the asynchronous call. "Continuation" simply means "the rest of the calculation, from a given point forward". In the code sample, that's the call to series.addPoint. The pattern for this is you transform:

function f(...) {
    (1)
    result = sync(...);
    (2)
}

into:

function f(...) {
    (1)
    async(..., function (result) {
          (2)
      });
}

If (2) returned a value in the original function, then the call to f must also be rewritten using continuation passing style, adding an extra parameter to hold the continuation.

The other thing you should do is make sure the PHP script outputs the numeric pair as valid JSON, either as an array of two numbers (which can be passed directly to the series.addPoint call after parsing), or as an object with properties "x" and "y".

Note that, due to the nature of network communication, the data may not arrive in a timely manner, resulting in a graph with irregular intervals.

Here's the gist, wrapping up the nuts-and-bolts of the asynchronous call into a function named ajaj. The sample assumes the browser supports the necessary standards for XMLHttpRequest and the JSON parser.

/* Asynchronous Javascript And Json */
function ajaj(url, succeed, fail) {
    if (! fail) {
        fail = function() {};
    }
    var xhr = new XMLHttpRequest;
    xhr.open('GET', url);
    xhr.onreadystatechange = function() {
        if (xhr.readyState==4) {
            if (200 <= xhr.status && xhr.status < 300) {
                succeed(JSON.parse(xhr.responseText));
            } else {
                // error
                fail(xhr.status, xhr.statusText, xhr.responseText);
            }
        }
    };
    xhr.send();
    return xhr;
}

...

    url: '...',

    load: function() {
        // ensure only one data load interval is running for this object
        if (this.updateInterval) {
            return;
        }
        // set up the updating of the chart each second
        var series = this.series[0];

        this.updateInterval = setInterval(function() {
            ajaj(this.url, 
                 function(point) { // success
                     series.addPoint(point, true, true);
                 },
                 function(status, statusText, response) { // failure
                     ...
                 }
            );
        }, 1000);
    }

JS libraries provide their own version of ajaj, often with more features. If you're doing anything of any complexity for a production site, look into adopting one. If you're using jQuery (as the tag suggests), you can, for example, use jQuery.get:

    load: function() {
        if (this.updateInterval) {
            return;
        }
        // set up the updating of the chart each second
        var series = this.series[0];

        this.updateInterval = setInterval(function() {
            jQuery.get(this.url, 
                 function(point, textStatus, jqXHR) { // success
                     series.addPoint(point, true, true);
                 }, 'json'
            );
        }, 1000);
    }

The server side of things is dead simple. time() returns a Unix timestamp, rand() returns a (not very) pseudorandom number (though good enough for a demo), and json_encode(), well, you can figure that out.

<?php
header('Content-type: application/json');

echo json_encode(
        array(
            time(),
            rand() / getrandmax(),
        ));



回答2:


I think you want a recursive call to setTimeout:

function update(series){
    var x = (new Date()).getTime(), // current time
        y = Math.random();
    series.addPoint([x, y], true, true);
    setTimeout(function() { update(series); }, 1000);
}

And then:

load: function() {            
    var series = this.series[0];
    update(series);
}

Or better yet, try something like this:

function update(){
    var series = yourChart.series[0];
    var x = (new Date()).getTime(), // current time
        y = Math.random();
    series.addPoint([x, y], true, true);
    setTimeout(update, 1000);
}

And then:

load: update

EDIT

If you're wanting to get a random number as an integer, something like this should do it (depending on the range of the number you want)

Math.floor(Math.random() * 10)

random will return a number in the range [0, 1), and floor will chop off any decimal points.

See random docs



来源:https://stackoverflow.com/questions/8570524/how-can-i-use-ajax-to-fetch-data-and-store-it-in-javascript-variables

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!