简体   繁体   English

JavaScript和HTML - 重用来自fetch()的数据

[英]JavaScript & HTML - reusing data from fetch()

I am retrieving a JSON file from my server using a basic fetch request as follows: 我正在使用基本提取请求从我的服务器检索JSON文件,如下所示:

function getDailyTranscripts (url) {
  fetch(url)
    .then(validateResponse)
    .then(readResponseAsJSON)
    .then(useDailyResult)
    .catch(logError)
}

This retrieves a master JSON file that I'm then creating variables from to populate multiple charts in a single html page using charts.js 这将检索一个主JSON文件,然后我创建变量,使用charts.js在单个html页面中填充多个图表

Currently I can make this work for an individual chart by running the code in the useDailyResult() function that is part of my fetch function. 目前,我可以通过运行useDailyResult()函数中的代码来使单个图表工作,该函数是我的fetch函数的一部分。 However, I will need to repeat this pattern for all of my charts individually and duplicate a lot of code, as well as server calls, with my current implementation. 但是,我需要单独为所有图表重复此模式,并使用我当前的实现复制大量代码以及服务器调用。

Here's the current useDailyResult function for one of my charts as an example: 这是我的一个图表的当前useDailyResult函数作为示例:

function useDailyResult (result) {

  var labels = Object.keys(getUsersByChannel2(result))
  var data = Object.values(getUsersByChannel2(result))

  var ctx = document.getElementById('chartOops').getContext('2d');
  var chart = new Chart(ctx, {
    type: 'doughnut',
    data: {
      labels: labels,
      datasets: [{
        label: 'Channels',
        data: data
      }]
    },
    options: {
      title: {
        display: true,
        text: 'Users by Channel'
      },
      legend: {
        position: 'bottom'
      },
      scales: {
        gridLines: {
          display: false
        }
      },
      plugins: {
        colorschemes: {
          scheme: chartColorScheme
        }
      }
    }
  });
}

The end result I want to get to is to retrieve the JSON file once from the server, store it locally (eg using HTML5's local storage), and then run all of my chartjs code against the locally-stored file. 我想要的最终结果是从服务器检索一次JSON文件,在本地存储它(例如使用HTML5的本地存储),然后针对本地存储的文件运行我的所有chartjs代码。 That way I can reduce the code and number of server calls. 这样我可以减少服务器调用的代码和数量。

I'm not sure the best way of doing this as the only way I know to access the JSON file is from within the fetch function. 我不确定这样做的最佳方式,因为我知道访问JSON文件的唯一方法是从fetch函数中。 I've also been looking into using Backbone.js as this could be a useful library. 我也一直在研究使用Backbone.js,因为这可能是一个有用的库。

You can reuse the data fetched from the server if you just assign it to a variable your function has access to. 如果只是将其分配给您的函数可以访问的变量,则可以重用从服务器获取的数据。

If you had another then in your chain that assigns to a var, then you can check that var before doing another fetch. 如果你有其他then在链中分配给一个变种,那么你可以做的是另取前检查变种。

var remoteData = {}

function getDailyTranscripts (url) {
  // check for existing response data based on url param
  if(remoteData[url]) {
    console.log('using pre-fetched data from memory')
    useDailyResult(remoteData[url])
  }
  else {
    console.log('fetching from server', url)
    fetch(url)
      .then(validateResponse)
      .then(readResponseAsJSON)
      .then(jsonData => {
        // assuming readResponseAsJSON returns what you want
        remoteData[url] = jsonData
        useDailyResult(jsonData)
      })
      .catch(logError)
  }
}

Note that if you call getDailyTranscripts a second time while the initial fetch is still working, it will kick off another fetch. 请注意,如果您在初始提取仍然有效时再次调用getDailyTranscripts ,它将启动另一次提取。 So you might want to add some logic to address that if it could be an issue for you. 所以你可能想要添加一些逻辑来解决这个问题,如果它可能是你的问题。

It may just be best to (1) read remote data, then (2) pass it along that whatever is going to need it, if you know that ahead of time. 最好(1)读取远程数据,然后(2)将其传递给任何需要它的东西,如果你提前知道的话。 But that just depends on your use case. 但这取决于您的用例。

fetch(url)
  .then(validateResponse)
  .then(readResponseAsJSON)
  .then(handleAllYourChartsAtOnce) // this function could also store the json in a var
  .catch(logError)

You can tell a promise p to call multiple handlers when it's available by calling p.then multiple times: 您可以通过多次调用p.then来告诉承诺p调用多个处理程序:

let data = fetch(url)
    .then(validateResponse)
    .then(readResponseAsJSON);

Promise.all([
  data.then(useDailyResult),
  data.then(buildAnotherChart)
]).catch(logError);

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

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