I have a function updateChartData
that uses a global variable array with information from a file server.
async function updateChartData(){
console.log("Updating chart with ID", 1);
await buildChartData(1).then(
console.log(workItems)
)
In addition to a function buildChartData
that refreshes the information in the array, this function has recursive behaviour.
async function buildChartData(currentID){
axios.get(`http://localhost:8888/_wit/workItems?id=${currentID}`).then(function(res){
let currentItem = res.data.value[0]
console.log(currentItem)
//Find child items
let childItemIds = []
for (let link in currentItem.Links){
let currentLink = currentItem.Links[link]
childItemIds.push([currentLink.TargetWorkItemId])
console.log("Found Child",currentLink.TargetWorkItemId)
};
workItems[currentItem.WorkItemId] = {
'Title':currentItem.Title,
'WorkItemType':currentItem.WorkItemType,
'State':currentItem.State,
'Links': childItemIds
};
//Recursion
if (currentItem.Links.length >0){
childItemIds.forEach(buildChartData)
};
});
};
The issue I am having is that despite explicitly creating an async function and using the await keyword. The program proceeds to resolve the await and move in to the then function.
This inconsistency means that inside of the updateChartData
function I do not have access to the full chart data.
The purpose of the application is essentially to find all nodes and verticies within a tree structure for "work items", served up on a file server. So the number of recursions necessary for a given request is unknown so i cannot use that as a means to delay resolving a promise. When the function runs to completion that data is valid, but it is sequence of events I am having difficulty with.
I have tried returning a promise within the async function but it resolves after the first recursion occurs.
Additionally, I have explored using the setTimeout
function with no success either.
I am finding synchronous bahaviours in JavaScript very difficult with complex functions, any help would be appreciated.
Edit:
Posting my working solution as it may be teachcable for other users.
using the await keyword inside and outside of the recursive for loop
async function buildChartData(currentID){ const res = await axios.get(
http://localhost:8888/_wit/workItems?id=${currentID}`)
let currentItem = res.data.value[0]
console.log(currentItem)
//Find child items
let childItemIds = []
for (let link in currentItem.Links){
let currentLink = currentItem.Links[link]
childItemIds.push([currentLink.TargetWorkItemId])
console.log("Found Child",currentLink.TargetWorkItemId)
};
workItems[currentItem.WorkItemId] = {
'Title':currentItem.Title,
'WorkItemType':currentItem.WorkItemType,
'State':currentItem.State,
'Links': childItemIds
};
//Recursion
if (currentItem.Links.length >0){
for await (const childId of childItemIds){
await buildChartData(childId)
};
};
};`
Then in the updateChartData function (which acts as main) the following code:
async function updateChartData(){
console.log("Updating chart with ID", state.trackedID);
await buildChartData(state.trackedID)
console.log(workItems)
These modifications make the program await all recursive actions and the workItems data is logged correctly.