Búsqueda de sitios web

javascript - Subir archivos grandes en partes usando nodejs


Estoy intentando subir archivos muy grandes en fragmentos a un servidor. El servidor funciona muy bien. En la función que he desarrollado, intenta subir todos los archivos de una vez. Soy nuevo en async/await y no estoy seguro de cómo proceder. El objetivo es simplemente subir uno a la vez en fragmentos.

Ten en cuenta que he extraído esto de una clase, lo he actualizado para mayor claridad y he eliminado todas las partes innecesarias.

Usando node-fetch para agregar fetch().

Gracias por cualquier ayuda o consejo :)

let tree = []

const start = () => {
    scan('/foo/bar', err => { 
        tree.forEach(file => {
            upload(file)
        })
    })
}

const scan = dir => { ... } // assigns array of files to tree

const upload = file => {
    const stream = fs.createReadStream(file) 
    stream.on('data', async chunk => {
        stream.pause()
        try {
            let response = await fetch('https://some/endpoint', {
                method: 'post',
                body: JSON.stringify({
                    file: file,
                    chunk: chunk.toString('base64')
                }) 
            })
            stream.resume()
        } catch(e) {
            // handle errors
        }
    })
    stream.on('end', () => {
       console.log('end', file)
    })
    stream.on('error', err => {
        console.log('error', err)
    })
}

Respuesta #1

Array.prototype.forEach se ejecuta de manera sincrónica hasta que se hayan procesado todos los elementos de un arreglo, descartando cualquier valor devuelto por la función argumento que llama.

Para subir un archivo a la vez, intenta usar await (dentro de una función asincrónica) para esperar a que cada archivo se suba, en combinación con devolver una promesa del proceso de subida que se cumpla cuando una subida se haya completado. Conceptualmente (sin manejo de errores elegante) podría verse así

const uploadTree = async tree => {
    for( file of tree) {
         await uploadFile( file); // process files one at a time
    }
}

// wrap the existing upload code in a promise executor:

const uploadFile = file => new Promise( (resolve, reject) => {
     const stream = fs.createReadStream(file)
     stream.on('data' ...
        ...
     } catch(e) {
        console.log( "Error uploading chunk of %s", file)
        reject(e) // handle errors
     }
     stream.on('end', resolve)
     stream.on('error', e=> {
        console.log(" Error reading %s", file)
        reject (e)
     })
});

// upload complete tree array files:

uploadTree(tree)
.then( ()=> console.log( "tree uploaded successfully"));
.catch( err=> console.log("An upload failed: ", err));