I've been trying to get this bit of code to work for a while, and I just can't seem to get it. It's for a live-updating graph, that takes in an array of [x, y] for each point, so an array of arrays.
The input is a JSON
list coming from a server, that updates that same JSON
object (so it changes one JSON
and updates only the value):
[
{
"Value": 10,
"Name": "Name of variable"
}
]
I need to extract the value only.
I tried it like this:
var getValueData = async function() {
var valueJSON = await Promise.resolve($.getJSON( "{% url 'get_value' %}" ));
return valueJSON[0]['Value'];
};
var data = [];
var totalPoints = 100;
var updateInterval = 1000;
var now = new Date().getTime();
function getData() {
data.shift();
while (data.length < totalPoints) {
var value = [now += updateInterval,
getValueData().then(function(result) {
result;
})
];
data.push(value);
};
};
Basically, getData()
is trying to build an array of X = timestamp.now()
, and Y = "Value"
from JSON
, then push that array into my "overall"
data array.
Doing it this way makes value
an array of [<timestamp>, Unresolved]
.
Doing it this way:
while (data.length < totalPoints) {
getZScoreData().then(function (result) {
var valueArray = [now += updateInterval, result];
data.push(valueArray);
});
};
Makes valueArray
be an actual [<timestamp>, <JSON "value"]
, if I console.log(value)
, except this way seems to hang the server forever and consume a huge amount of RAM for the tab, as if I was doing an infinite loop (hundreds of get requests to the web server, even though the max length should 100). I'm not sure of the what's going inside the Promise to get this behavior though.
This here is the code that works in the example:
while (data.length < totalPoints) {
var y = Math.random() * 100;
var value = [now += updateInterval, y];
data.push(value);
};
It seems straightforward enough. Where it says y (in var value = [now += updateInterval, y];
) make "y" get the value from my API.
I have no clue how to actually achieve this.
I'm following the example from this Flot example but I just can't manage to make it work with an actual live value from AJAX or Promise (I even tried fetch).
All examples for "live updating table" end up just using math.random()
, which is pretty misleading, as it just kinda moves about, but isn't really live.
I believe I'm not resolving the promise in the loop properly, but due to lack of experience, at this point I'm not even sure what is wrong.
I'm not sure where in my code I would go Y = "live value"
, or whether I have to return result somewhere? I'm not familiar with Promises or AJAX that much.
Promises in loops are rarely a good idea, you'll usually want to use Promise.all()
to execute multiple Promises at once, and get their results collected in an array:
function getData() {
// Note: Why is this here?
data.shift();
var promises = [];
while (data.length < totalPoints) {
promises.push(getValueData());
}
Promise.all(promises).then(results => {
for (let result of results) {
var value = [
now += updateInterval,
result
];
data.push(value);
}
});
};
MDN has some good materials on Promises: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Using_promises
As a side note, executing 100 AJAX requests at the same time sounds pretty strenuous, even with Promise.all()
. You should either try to optimize the backend if you have any influence over it, or look into Worker
s to execute the requests in batches.