【问题标题】:Javascript multiple function setTimeout syncing problems, or is there a better way?Javascript 多函数 setTimeout 同步问题,还是有更好的办法?
【发布时间】:2019-03-04 00:34:01
【问题描述】:

好的,所以我遇到了一些问题。我想利用来自一个数据源的数据使用 CanvasJS 创建多个图表。问题是我每 60 秒更新一次图表,当我运行更新函数时,它最终会为它正在更新的每个图表调用一次我的外部 JSON,这并不理想。所以我试着把事情放在单独的计时器循环上,每 60 秒设置一次,但在两个不同的函数上,它可以工作,但我注意到有时更新的数据几乎落后 2 分钟,想想就像落后 1m 50 秒左右。这也不理想。我的代码非常简洁,看起来像这样......

var updatedData = {}; // start empty

function updateData() {
    $.getJSON("/update.php", function (data) {
       updatedData = data; // new data for datapoints
    });
}

function makeGraph(dataValue, color) {
    // ... bunch of code here for making the graph and setting url's to use

    $.getJSON(url, function(data) { // bring in initial data
        $.each(data[dataType], function(k,v) {
            // handle data for each dataType setting datapoints to be graphed
        }
        linechart.render(); // create initial chart
    });

    function updateLineChart() { // ok let's update each chart...

        $.when(updateData()).done(function() {
            // use updated data for new set of datapoints
            linechart.render();// add new data to current chart
        }

        setTimeout(function() {
            updateLineChart(); // run update every 60 seconds
        }, 60000);
    }
    updateLineChart(); // initially run update
}

这工作得很好,但不幸的是,它会为它正在渲染的每个图表调用 update.php,而 udpate.php 实际上会在每次调用时发送所有图表的数据,因此无需调用它 3,4,每分钟5次或更多。像这样调用数据时,数据保持最新,1分钟以内或实时,准确度好。

我已多次重做此操作,试图通过多种不同的方法摆脱额外的调用。我所做的一个只调用它一次但很有可能会出现滞后数据的情况就是这样......

var updatedData = {}; // start empty

function updateData() {

    $.getJSON("/update.php", function (data) {
       updatedData = data; // new data for datapoints
    });

    setTimeout(function() {
        updateData(); // run data update every 60 seconds
    }, 60000);
}

updateData(); // run data update initially

function makeGraph(dataValue, color) {
    // ... bunch of code here for making the graph
    $.getJSON(url, function(data) { // bring in initial data
        $.each(data[dataType], function(k,v) {
            // handle data for each dataType setting datapoints to be graphed
        }
        linechart.render(); // create initial chart
    });

    function updateLineChart() { // ok let's update each chart...
            // use updated data for new set of datapoints
            linechart.render(); // add new data to current chart
        }
        setTimeout(function() {
            updateLineChart(); // run update every 60 seconds
        }, 60000);
    }
    updateLineChart(); // initially run update
}

这样做,它们在不同的 setTimeout 循环中,因此数据仍然接近实时,但我注意到它通常几乎落后了整整两分钟。另外,为了记录,我尝试设置便宜的技巧,例如创建新日期,查看日期是否与 utcSeconds(0) 匹配,如果日期不匹配,则仅获取 update.php 无济于事。它仍然会多次抓取 update.php。

谁能想出一种方法让它们保持同步,运行多个图表并且只调用一次来获取数据?我在这方面的想法已经不多了。

【问题讨论】:

    标签: javascript jquery settimeout each


    【解决方案1】:

    您可以尝试以下方法:

        function updateData() {
           return $.getJSON("/update.php", function (data) {
              return data; // new data for datapoints
           });   
        }
    
        function updateLineChart(lineChartData) { 
            // use updated data for new set of datapoints
            linechart.render(); // add new data to current chart
        }
    
        function updateGraphs() {
            updateData().then(function(grphData){
                //foreach var crtData in grphData --> not sure who you key the data here                 in your response
            updateLineChart(grphData[cIndex])
            })
        }
    
        //initiallize with empty data
        //foreach var crtData in grphData --> not sure who you key the data here in your response
        updateLineChart({})
    
        setInterval(function() {
            updateGraphs(); // run data update every 60 seconds
        }, 60000);
    

    【讨论】:

    • 虽然这不能完全按原样工作,但由于一些函数是嵌套的,我知道你在做什么,让我试一试,我会告诉你的。谢谢你的主意!聪明的做法!
    【解决方案2】:

    试试这样的:

    var timeoutId = undefined;//In global scope
    
    //whenever you set new timeout first clear old one and then create new
    if (timeoutId) {
        clearTimeout(timeoutId);
    }
    timeoutId = setTimeout(function() {
        updateData(); // run data update every 60 seconds
    }, 60000);
    

    HTH

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-17
      • 1970-01-01
      • 2020-09-15
      相关资源
      最近更新 更多