this is my problem: I need to make some fetch POST requests to my server. The server holds a list of names. Each name corresponds to a list of elements which I need to browse, in order to find a specific element from all the lists. I have to work with this structure, can't change it.
My approach was to write a fetch request, to get the all these names (of the lists I need to browse), then I would loop through each name and fetch to get the according lists from the server. Once I get these lists I can loop through the elements till I find the correct element.
This is not an easy task for me as I am new to javascript.
This is how I implemented this:
function browse(){
fetch(TARGET_IP, {
method: "POST",
headers: {
"Content-type": "application/json",
"X-Auth-Token": AUTH_TOKEN
},
body: JSON.stringify({
"id": messageId++,
"jsonrpc": "2.0",
"method": "Browse",
"params": {
"mode": "children"
}
})
})
.then(response => response.json())
.then((data) => {
data.results = Object.assign(Array.prototype, data.result);
data.results.forEach(element => {
if (element.datatype == "datablock") {
datablocks.push(element.name)
}
})
return datablocks;
})
.then((datablocks) => {
datablocks.forEach(element => {
browseDatablocks(element)
})
})
.catch(e => console.error(e))
}
function browseDatablocks(dbname) {
fetch(TARGET_IP, {
method: "POST",
headers: {
"Content-type": "application/json",
"X-Auth-Token": AUTH_TOKEN
},
body: JSON.stringify({
"id": messageId++,
"jsonrpc": "2.0",
"method": "Browse",
"params": {
"var": "\"" + dbname + "\"",
"mode": "children"
}
})
})
.then(response => response.json())
.then((data) => {
data.results = Object.assign(Array.prototype, data.result);
data.results.forEach(element => {
if (element.name == "P_Index")
{
console.warn(dbname);
// This is the element I need and would save it
}
})
})
.catch(e => console.error(e))
}
Now all sorts of strange things happen with this approach.
The console outputs elements that are just not the elements I search for, which is just wrong as I checked on server side.
Some requests are not even handled.
I assume these problems occur because I send too many requests at the same time (the nested ones in browseDatablocks). How can I handle one request and then the next one? Or are there other ways to implement this?
Thanks.
looks like what you need is Promise.all.
if i understand the problem correctly:
first return the fetch result in function browseDatablocks(dbname)
...
function browseDatablocks(dbname) {
return fetch(TARGET_IP, {
....
And return the value, in last then
.then((data) => {
data.results = Object.assign(Array.prototype, data.result);
const filtered = data.results.filter((element) => element.name == "P_Index");
return filtered;
});
Then in function browse()
, last then:
.then((datablocks) => {
const results = datablocks.map(element => browseDatablocks(element));
return Promise.all(results);
})
.then((listOfResults) => {
// Some magic here
})
// Edit or to do them in order:
In function browseDatablocks(dbname)
, last then:
do the handling, and return a bool
instead of filtered
eg true
= all done, false
fetch the next. Something like:
.then((data) => {
data.results = Object.assign(Array.prototype, data.result);
const found = data.results.find(element => element.name == "P_Index");
if (found) {
// Some handling
return true;
}
return false;
})
And in function browse()
, last then
.then(async (datablocks) => {
let i = 0;
while(i < datablocks.length) {
const handled = await browseDatablocks(datablocks[i]);
if (handled === true) {
break;
}
i += 1;
}
});