Проблема при загрузке массива, инициализированного в другом скрипте, на веб-странице - PullRequest
1 голос
/ 16 апреля 2019

Это кажется нелепо простой вещью, но я до сих пор не могу понять это. Я использую скрипт для получения и структурирования некоторых данных из веб-API. Он помещает все это в массив, а затем другой скрипт, который должен загрузиться чуть позже, использует эти данные для построения диаграммы с Highcharts.

Мой скрипт извлечения данных выглядит так:

var dataSeries = [];

fetch('https://eu-west-1.aws.webhooks.mongodb-stitch.com/api/client/v2.0/app/semapres-charts-dsioa/service/get-chart-data/incoming_webhook/get-day?secret=secret').then(
    function(response){
        return response.json();
    }
).then(function(jsonData){
    for (let i=0;i<jsonData.length;i++) {
        dataSeries.push([jsonData[i][0].$date.$numberLong, jsonData[i][1].$numberDouble]);
    }
});

Мой скрипт Highchart выглядит так:

$(window).load(function () {
        let dataSeriesTest = [[1555318393000, 103.28],[1555318423000, 104.28]];
        var myChart = Highcharts.chart('highchart-container', {
            chart: {
                zoomType: 'x'
            },
            title: {
                text: 'Time'
            },
            xAxis: {
                type: 'datetime'
            },
            yAxis: {
                title: {
                    text: 'Pressure (kPa)'
                }
            },
            series: [{
                name: 'Sensor0',
                data: dataSeries
            }]
        });
});

И хотя моя html-страница очень длинная, в верхней ее части есть:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Sematek Pontongtrykk</title>
  <link rel="stylesheet" href="styles.css">
  <script src="https://s3.amazonaws.com/stitch-sdks/js/bundles/4.3.1/stitch.js"></script>
  <script src="https://code.jquery.com/jquery-1.7.2.js"></script>
  <script src="data-fetch.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/paho-mqtt/1.0.1/mqttws31.min.js" type="text/javascript"></script>
  <script src="app.js"></script>
  <script src="https://code.highcharts.com/highcharts.js"></script>
  <script src="highcharter.js"></script>
</head>
<body>

И это близко к нижней части страницы:

  <div id="highchart-container" width="100%" height="400"></div>

Я получаю диаграмму для рисования, она выглядит хорошо с моими тестовыми данными, но при отладке я получаю, что мой Array dataSeries имеет длину 0 внутри скрипта Highcharts. Также кажется, что этот сценарий отлаживается перед моим сценарием сбора данных, несмотря на использование метода загрузки jQuery. Я уверен, что мой скрипт сборщика данных работает и создает из него массив.

Ответы [ 3 ]

1 голос
/ 16 апреля 2019

Вы должны загрузить данные в том же сценарии, в котором вы создаете диаграмму:

$(window).load(function() {
    var dataSeries = [];

    fetch('https://eu-west-1.aws.webhooks.mongodb-stitch.com/api/client/v2.0/app/semapres-charts-dsioa/service/get-chart-data/incoming_webhook/get-day?secret=secret').then(
        function(response) {
            return response.json();
        }
    ).then(function(jsonData) {
        for (let i = 0; i < jsonData.length; i++) {
            dataSeries.push([jsonData[i][0].$date.$numberLong, jsonData[i][1].$numberDouble]);
        }

        createChart();
    });

    function createChart() {
        var myChart = Highcharts.chart('highchart-container', {
            ...
        });
    }
});

Демонстрационная версия: http://jsfiddle.net/BlackLabel/hdjqgebt/

В качестве альтернативы выможно добавить скрипт app.js после загрузки данных:

var dataSeries = [];

fetch(...).then(function(jsonData) {
    for (let i = 0; i < jsonData.length; i++) {
        ...
    }

    var script = document.createElement('script');
    script.src = "app.js";
    document.getElementsByTagName('head')[0].appendChild(script);
});
1 голос
/ 16 апреля 2019

Ваша основная проблема - асинхронное поведение.

Я предполагаю, что ваш app.js содержит инициализацию и выборку массива, что означает, что он начнет выполняться до highcharter.js, но ваш массив не будет заполнен сразу, так как выборка занимает время.

Вот почему продолжение цепочки обещаний решит вашу проблему.

$(window).load(() => {
  fetch('...')
    .then(res => res.json())
    .then(data => data.map(item => [parseInt(item[0].$data.$numberLong), parseFloat(item[1].$numberDouble)]))
    .then(doTheMagicWithHighcharter);
})

Обратите внимание, что вам не нужно инициализировать массив dataSeries, потому что вы передаете его по цепочке.

0 голосов
/ 16 апреля 2019

Для тех, у кого такая же проблема, я нашел решение, которое продолжало цепочку обещаний, чтобы передать данные в бит Highcharts.

Это результат обоих сценариев:

$(window).load(function () {
    let dataSeries = [];
    fetch('https://eu-west-1.aws.webhooks.mongodb-stitch.com/api/client/v2.0/app/semapres-charts-dsioa/service/get-chart-data/incoming_webhook/get-day?secret=secret').then(
        function (response) {
            return response.json();
        }
    ).then(function (jsonData) {
        for (let i = 0; i < jsonData.length; i++) {
        let time = jsonData[i][0].$date.$numberLong;
        let val = jsonData[i][1].$numberDouble
            dataSeries.push([parseInt(time),parseFloat(val)]);
        }
        return dataSeries;
    }).then(function (dataSeries) {
        let myChart = Highcharts.chart('highchart-container', {
            chart: {
                zoomType: 'x'
            },
            title: {
                text: 'Time'
            },
            xAxis: {
                type: 'datetime'
            },
            yAxis: {
                title: {
                    text: 'Pressure (kPa)'
                }
            },
            series: [{
                name: 'Sensor0',
                data: dataSeries
            }]
        });
    });
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...