Búsqueda de sitios web

javascript - ¿Problemas asíncronos con FileReader readAsText()?


He implementado el siguiente código para analizar un CSV a través de una selección <input type="file" />:

export async function parse(file: File) {
  let content = '';
  const reader = new FileReader();
  reader.onload = function(e: any) {
    content = e.target.result;
  };
  await reader.readAsText(file);
  const result = content.split(/\r\n|\n/);
  return result;
}

Si ejecuto este código y pongo un punto de interrupción en la línea donde declaro result, recupera el contenido del archivo correctamente. Si no pongo ningún punto de interrupción, el contenido está vacío. Como puedes ver, añadí await en la línea donde el lector lee el archivo como texto, pero todavía no funciona.

Respuesta #1

await no ayuda aquí. readAsText() no devuelve un Promise.

Necesitas envolver todo el proceso en un Promise:

export function parse(file: File) {
  // Always return a Promise
  return new Promise((resolve, reject) => {
    let content = '';
    const reader = new FileReader();
    // Wait till complete
    reader.onloadend = function(e: any) {
      content = e.target.result;
      const result = content.split(/\r\n|\n/);
      resolve(result);
    };
    // Make sure to handle error states
    reader.onerror = function(e: any) {
      reject(e);
    };
    reader.readAsText(file);
  });
}

Respuesta #2

Aquí está el JSBin que he probado y funciona de maravilla.

function parse(file) {
  const reader = new FileReader();
  reader.readAsText(file);
  reader.onload = function(event) {
    // The file's text will be printed here
  console.log(reader.result)
  }
}

Actualizado:

Te escribo una versión de Promesa.

async function parse(file) {
  const reader = new FileReader();
  reader.readAsText(file);
  const result = await new Promise((resolve, reject) => {
    reader.onload = function(event) {
    resolve(reader.result)
    }
  })
  console.log(result)
}

Artículos relacionados