Tengo un archivo JSON con una lista de valores de descuento, estoy usando Remark para analizarlos en HTML. Después de analizar cada valor, lo agrego a un objeto para que sea accesible, sin embargo, creo que me estoy quedando atascado en algún lugar de la tierra prometida porque los valores en el objeto no están definidos.
let sections = {}; const parseMD = (val) => { let parse = new Promise((resolve, reject) => { const file = unified() .use(remarkParse) .use(remarkRehype) .use(rehypeStringify) .process(val.body); resolve(file); }); parse.then( function (str) { sections[val.id] = str.value; } ); return parse; } contents.forEach((val) => parseMD(val).then((val) => val).catch(err => console.log(err))); Por lo que sé, esto debería funcionar... Si agrego un console.log(sections) obtengo {} , que parece un objeto vacío pero cuando lo amplío veo que todo mi contenido está ahí:
section1: "blah blah blah", section2: "something else" ... Pero sections[section1] no estarán undefined .
Siento que me estoy retrasando en la promesa en alguna parte, pero no sé cómo solucionarlo.
También probé esto con async/await en el bucle for: content.sections.forEach(async (val) => await parseMD(val)); mismos resultados.
Si agrego un
console.log(sections), obtengo{}
Esto probablemente se deba a que realiza esta salida como parte de la ejecución síncrona y no espera a que se resuelva la promesa. En resumen, solo debe imprimir sections cuando se encuentre dentro de then devolución de llamada, ya que solo se ejecutará cuando el objeto se haya completado.
No es su problema, pero no debe crear una new Promise cuando ya tiene una, ya que no aporta ningún valor adicional.
Además, es una mala práctica mutar una variable global ( sections ) dentro de una función. En su lugar, deje que su parseMD sea más independiente y deje que se resuelva en la información que necesita para esa cadena de entrada (el id y el value ), y déjelo al usuario de esa promesa para combinar esos pares de información en sections de un objeto .
Así que hazlo así:
const parseMD = (val) => unified() .use(remarkParse) .use(remarkRehype) .use(rehypeStringify) .process(val.body) .then(str => [val.id, str.value]); // No access to `sections` here! Just the pair Promise.all(contents.map(parseMD)) // Wait for ALL those little promises to resolve .then(Object.fromEntries) // Collect the pairs into an object .then(sections => { // This is the accumulated object we need // Do all you wish to do with sections here (not in global scope) console.log(sections); }) .catch(console.log);