I am working on a gridsome project, where I am manipulating a schema and rendering pages based on that. So, I am passing a reference of schema to a function, which function will manipulate a deeply nested object like,
{
URL: "some.url"
paramas: {"some params}
}
to
{
URL: "some.url"
params: {"some params}
props:{
data:[] || {}
}
}
this manipulation will happen based on the URL and param, so I need to use forEach loop but unfortunately, forEach loop is not asynchronous.
Here I am out of ideas what I need to do if I want to manipulate all those objects (more than 100) from other module and it has to be asynchronous.
a demo schema:
{
"name": "home",
"path": "/",
"header": "top_header",
"footer": "bottom_footer",
"rows": [
{
"row_class": "bg-white",
"columns_class": "cols-66-33 cols-separated cols--height-equal",
"column_1": [
{
"name": "Coral/HomeNews",
"props": {
"tag": "main"
}
}
],
}
]
}
edit: So I am calling a function from other module like
await dataExtender(_schema);
which contains a function(currently I am developing it, and not complete) which is
const dataExtender = async _schema => {
// Define forEach function
console.log(chalk.green("Data Extending starts from module level"));
await Promise.all(
_schema.pages.forEach(async page => {
page.rows.forEach(row => {
row.column_1.forEach(async column => {
if (column.url !== undefined) {
await axios
.post(column.url, column.param || {})
.then(data => {
console.log(chalk.green("Extending"));
if (Array.isArray(data.data)) {
column.props.data = [...data.data];
} else {
column.props.data = { ...data.data };
}
})
.catch(err => {
console.log(err);
});
}
});
if (row.column_2 !== undefined) {
row.column_2.forEach(async column => {
if (column.url !== undefined) {
await axios
.post(column.url, column.param || {})
.then(data => {
column.props.data = data.data;
})
.catch(err => {
console.log(err);
});
}
});
}
});
}),
);
console.log(chalk.green("Data Extending finishes from module level"));
return _schema;
};
CodePudding user response:
While forEach
itself is not async-aware, that doesn't stop you from being able to push the asynchronous modification promises onto a list and awaiting for all of them at the end.
import axios from "axios";
async function processColumn(column) {
const data = await axios.post(column.url, column.param || {});
console.log(chalk.green("Extending"));
if (Array.isArray(data.data)) {
column.props.data = [...data.data];
} else {
column.props.data = { ...data.data };
}
}
async function processColumn2(column) {
const data = await axios.post(column.url, column.param || {});
column.props.data = data.data;
}
const dataExtender = async (_schema) => {
console.log(chalk.green("Data Extending starts from module level"));
const promises = [];
_schema.pages.forEach((page) => {
page.rows.forEach((row) => {
row.column_1.forEach((column) => {
if (column.url !== undefined) {
promises.push(processColumn(column));
}
});
if (row.column_2 !== undefined) {
row.column_2.forEach((column) => {
if (column.url !== undefined) {
promises.push(processColumn2(column));
}
});
}
});
});
await Promise.all(promises);
console.log(chalk.green("Data Extending finishes from module level"));
return _schema;
};