Область видимости массивов. Как сохранить данные в fetch...then?

Доброго времени суток, Я использую графики ApexCharts на JS:
let data;
        let exchangeName = [], longRate = [], shortRate = [];
        
        fetch("https://fapi.coinglass.com/api/futures/longShortRate?symbol=BTC&timeType=3")
            .then(response => response.json()
        )
        .then (data => {
            console.log(data['data'][0]);
            
            for (i = 0; i < data['data'][0]['list'].length; i++) {
                longRate[i] = data['data'][0]['list'][i]['longRate'];
                shortRate[i] = data['data'][0]['list'][i]['shortRate'];
                exchangeName[i] = data['data'][0]['list'][i]['exchangeName'];
            }            
        });    
        
    
        if ($('#sales').length) {
            var options = {
                    series: [{
                        name: 'Лонг',   
                        data: longRate,
                        }, {
                        name: 'Шорт',
                        data: shortRate,
                        },
                    ],
                      chart: {
                      id: 'longshortratio',   
                      type: 'bar',
                      height: 350,
                      stacked: true,
                      stackType: '100%'
                    },
                    plotOptions: {
                      bar: {
                        horizontal: true,
                      },
                    },
                    
                    xaxis: {
                      categories: exchangeName,
                      labels: {
                        formatter: function (val) {
                          return val
                        }
                      }
                    },
                
            };
            
            var chart = new ApexCharts(
                document.querySelector("#sales"),
                options
            );
            
            chart.render();
        }

Мне необходимо сначала получить данные с API и потом положить эти значения в график. Данные приходят успешно, но внутри fetch...then, за её пределами мне не получается использовать массивы exchangeName = [], longRate = [], shortRate = [];
Подскажите, как сделать область видимости массивов за пределами этой конструкции? Перекинуть код с конструкцией if ($('#sales').length) внутрь fetch.then не получится, потому что потом я обновляю данные и он не распознаёт chart.render();

Спасибо.
  • Вопрос задан
  • 99 просмотров
Пригласить эксперта
Ответы на вопрос 2
neuotq
@neuotq
Прокрастинация
Смотрите, во-первых вы немного нарушили логику потока данных у вас в приложении. С одной стороны, вы используете асинхронный fetch, с другой пытаетесь в синхронном режиме инициализировать ApexCharts. В момент создания options и ApexCharts да, там будет не то что вы ожидаете.
Поэтому вам нужно либо асинхронно создавать всё: грубо говоря засунуть в то место, где у вас и цикл, либо немного иначе использовать ApexCharts.
Инициализировать его с пустыми данными и текстом загрузка, а потом через updateSeries обновить график, тоже внутри того же .then (data => ...) после цикла, те асинхронно после того, как пришли данные.
Читайте тут:
https://apexcharts.com/docs/update-charts-from-jso...
Ответ написан
Rst0
@Rst0
разжевал для понимания, можно множеством способов на самом деле...
let data, 
chart, 
result = {longRate: [], shortRate: [], exchangeName: []},      // объявляем сразу как объект
options = { series: [], chart: {}, plotOptions: {}, xaxis: {}};  // тоже объявляем сразу как объект

и потом
fetch("https://fapi.coinglass.com/api/futures/longShortRate?symbol=BTC&timeType=3")
            .then(response => response.json()
        )
        .then (data => {
            console.log(data['data'][0]);
            if(data['data'].length > 0){                          // нужно  проверить хотя бы так
                 for (i = 0; i < data['data'][0]['list'].length; i++) {
                     result.longRate[i] = data['data'][0]['list'][i]['longRate'];
                     result.shortRate[i] = data['data'][0]['list'][i]['shortRate'];
                     result.exchangeName[i] = data['data'][0]['list'][i]['exchangeName'];
                } 
          
                checkSales(result);      //  вызываем проверку #sales  (внутри then )
           }else{
               console.log('no data');
           }
}); 
function checkSales(result){   //    это теперь отдельная функция
     if ($('#sales').length) {
              options.series: [{                    // без var
                        name: 'Лонг',   
                        data: result.longRate,          //  < --    result['longRate']
                        }, {
                        name: 'Шорт',
                        data: result.shortRate,         //  < --    result['shortRate']
                        },
             ];
             options.chart: {
                      id: 'longshortratio',   
                      type: 'bar',
                      height: 350,
                      stacked: true,
                      stackType: '100%'
              };
              options.plotOptions: {
                      bar: {
                        horizontal: true,
                      },
              };
                    
              options.xaxis: {
                      categories: result.exchangeName,      //  < --   result['exchangeName']
                      labels: {
                        formatter: function (val) {
                          return val
                        }
                      }
               };
              chart = new ApexCharts(             // без var
                        document.querySelector("#sales"),
                        options      
               );
            
            chart.render();
            }
 }
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы