Tengo una matriz anidada de objetos Person .
Cada objeto Person tiene un name obligatorio. Cada Person también puede tener opcionalmente un campo de children que contiene una matriz de otros objetos de Person (que también tienen un campo de niños, por lo que la "profundidad" del árbol genealógico puede continuar para siempre).
Si no hay hijos, el campo de los hijos será simplemente una matriz vacía [].
P.ej
const family_name = "The Numbers"; const family = [{ name: "1", children: [], }, { name: "2", children: [{ name: "2-1", children: [{ name: "2-1-1", children: [], }, ], }, { name: "2-2", children: [], } ], }, { name: "3", children: [{ name: "3-1", children: [], }, ], }, ] Necesito PUBLICAR el "padre" antes que el "hijo". Cuando PUBLIQUE una Person , obtengo su id en el response.data . Esta id debe usarse en el POST del niño inmediato como parent_id para que el niño se asocie al padre.
La Person más alta deberá tener su parent_id como family_name .
Cada "nivel" debe publicarse de forma asíncrona, ya que mi back-end debe conservar el orden. (Nota: Calcular el pedido de la Person en el lado del cliente y pasar ese valor al back-end no es una solución, ya que la Person es en realidad un modelo MPTT donde el orden de inserción es importante).
Por ejemplo, 1 luego 2 luego 3
Por ejemplo, 2 luego 2-1 luego 2-2 .
Sin embargo, las Person s anidadas se pueden POSTear de forma sincronizada. Por ejemplo, una vez que POSTing 2 regresa con una respuesta 201, su "hermano" 3 y su "hijo" 2-1 pueden enviarse POST al mismo tiempo.
¿Cómo puedo publicar de manera óptima todas las Person en una matriz anidada para que se conserve el orden? Tenga en cuenta que estoy usando axios.
Editar: Aquí hay un pseudocódigo:
function postPersons(persons, parent_id) { // Async POST all objects in persons // eg POST 1 then 2 then 3 to family_name // For each successful POST, if person has children, // async POST those children to that person // eg Once POST to 2 resolves, POST 2-1 then 2-2 to 2 // eg Once POST to 3 resolves, POST 3-1 to 3 // Repeat for all successful POSTs // eg Once POST to 2-1 resolves, POST 2-1-1 to 2-1 } postPersons(family, family_name)En lugar de usar async / await para un ciclo secuencial, recomendaría usar un ciclo síncrono y acumular dos cosas por separado:
Promise.all 'd al finalEsto asegura el orden correcto así como la propagación inmediata de errores.
Así que el código se verá como
function postPersons(persons, parent_id) { const results = []; let chain = Promise.resolve(); for (const person of persons) { chain = chain.then(() => postSinglePerson(person, parent_id) ); results.push(chain.then(result => postPersons(person.children, result.id) )); } return Promise.all(results); } postPersons(family, family_name).then(() => console.log('Done'), console.error);