简体   繁体   English

如何使用AJAX提取数据并将其存储在javascript变量中?

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

This is a sample dynamically updated chart: http://www.highcharts.com/demo/dynamic-update 这是一个示例动态更新的图表: 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. 图表每秒更新一次,日期为x值,随机数为y值。

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? 如何使用AJAX重写load以从另一个网页获取xy ,而不是在函数中生成值?

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. 我认为您想要的是样本load方法,但是将设置xy替换为AJAX调用。 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". Continuation ”仅表示“从给定点开始的其余计算”。 In the code sample, that's the call to series.addPoint . 在代码示例中,这就是对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. 如果(2)在原始函数中返回了值,则还必须使用延续传递样式重写对f的调用,并添加一个额外的参数来保存延续。

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". 您应该做的另一件事是确保PHP脚本将数字对输出为有效JSON,或者是两个数字的数组(可以在解析后直接传递给series.addPoint调用),或者作为具有属性“ x”和“ 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 . 这是要点,将异步调用的基本内容包装到一个名为ajaj的函数中。 The sample assumes the browser supports the necessary standards for XMLHttpRequest and the JSON parser. 该示例假定浏览器支持XMLHttpRequestJSON解析器的必要标准。

/* 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. JS库提供自己的ajaj版本,通常具有更多功能。 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 : 如果您使用的是jQuery(如标签所示),则可以使用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. time()返回一个Unix时间戳, rand()返回一个(不是非常)伪随机数(尽管足以演示),还有json_encode() ,您可以弄清楚。

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

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

I think you want a recursive call to setTimeout : 我认为您想要递归调用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. random将返回范围为[0,1)的数字,并且floor将截去任何小数点。

See random docs 查看随机文件

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM