Saltar al contenido

Leer un archivo sincrónicamente en Javascript

Solución:

Puede usar FileReaderSync estándar, que es una versión más simple, sincrónica y de bloqueo de la API de FileReader, similar a la que ya está usando:

let reader = new FileReaderSync();
let result_base64 = reader.readAsDataURL(file); 

console.log(result_base64); // aGV5IHRoZXJl...

Sin embargo, tenga en cuenta que esto solo está disponible en subprocesos de trabajo, por razones obvias.


Si necesita una solución para el hilo principal que “se lee como” una API síncrona, es decir, secuencialmente, puede envolver el FileReader asíncrono en una promesa y usar funciones asíncronas (es posible que necesite transpilar):

async function readFileAsDataURL(file) {
    let result_base64 = await new Promise((resolve) => {
        let fileReader = new FileReader();
        fileReader.onload = (e) => resolve(fileReader.result);
        fileReader.readAsDataURL(file);
    });

    console.log(result_base64); // aGV5IHRoZXJl...

    return result_base64;
}

Y luego puede esperar esta función en otro contexto asincrónico:

async function main() {
    let file = new File(...)
    let dataURL = await readFileAsDataURL(file)
    console.log(dataURL); // aGV5IHRoZXJl...
}

… o simplemente consúmalo usando promesas de devolución de llamada (no necesita un contexto asíncrono):

readFileAsDataURL(file).then(dataURL => {
    console.log(dataURL); // aGV5IHRoZXJl...
});

Las tareas sincrónicas (bloqueo) son generalmente malas. Si no hay una razón real para hacerlo de forma sincrónica, le recomiendo encarecidamente que utilice la devolución de llamada del evento.

Imagine que su archivo está roto y la API HTML5 no puede leer, no le dará el resultado. Rompería su código y bloquearía el sitio. O, alguien podría seleccionar un archivo de 10GB, lo que congelaría su página HTML hasta que el archivo esté completamente cargado. Con ese controlador de eventos asincrónico, podrá detectar posibles errores.

Para evitar las limitaciones con devoluciones de llamada, utilizo un truco simple:

var ready = false;
var result="";

var check = function() {
    if (ready === true) {
         // do what you want with the result variable
         return;
    }
    setTimeout(check, 1000);
}

check();

var reader = new FileReader();
reader.onloadend = function(evt) {
    // file is loaded
    result = evt.target.result;
    
    ready = true;
};
reader.readAsDataURL(file);

la función de verificación, verifica cada segundo si la variable de indicador listo está establecida en verdadera. Si es así, puede estar seguro de que el resultado está disponible.

Puede que no sea una buena práctica hacerlo, pero hice una aplicación web usando esta técnica unas 30 veces con más de 10 setTimeouts al mismo tiempo ejecutándose, y no experimenté ningún problema hasta ahora.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *