Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

217
Vistas
How to return value in sequential forEach loop?

This is how I'm using a sequential forEach loop to handle some file uploads. Now I want to get a total result for each upload: For each file I resolve with an object (success or error). At the end I want to get a returned array to display the result (File 1 successful, file 2 error and so on).

But with this code I only get undefined for the last output. What am I missing?

Maybe it would even be better to return two string arrays: one successful and one failed array with filenames.

Array.prototype.forEachSequential = async function (
    func: (item: any) => Promise<void>
): Promise<void> {
    for (let item of this) await func(item)
}
async uploadFiles(files: [File]): Promise<any> {
    const result = await files.forEachSequential(
        async (file): Promise<any> => {
        const res = await new Promise(async (resolve, reject) => {
            // do some stuff
            resolve({ success: file.filename })
            // or maybe
            resolve({ error: file.filename })
        })
        console.log(res) // returns object as expected
        return res
        }
    )
    // Get all results after running forEachSequential
    console.log('result', result) // result: undefined
})
about 4 years ago · Juan Pablo Isaza
2 Respuestas
Responde la pregunta

0

Your forEachSequential function has no return statement, so it never returns anything, so calling it will always result in undefined (in this specific case, a promise that's fulfilled with undefined, since it's an async function). It completely ignores the return value of the callback.

You probably want a mapSequential (or mapSerial) instead, that builds an array of the results:

Object.defineProperty(Array.prototype, "mapSequential", {
    async value(func) {
        const result = [];
        for (const item of this) {
            result.push(await func(item));
        }
        return result;
    },
    writable: true,
    configurable: true,
});

Note: I recommend you don't add to Array.prototype. Consider doing this instead:

async function mapSequential(iterable, func) {
    const result = [];
    for (const item of iterable) {
        result.push(await func(item));
    }
    return result;
}

But if you do add to Array.prototype, be sure to do it with defineProperty as I did above, not just with assignment, and make sure the property you add isn't enumerable (either use enumerable: false or leave it off, false is the default).

You can spin this a lot of ways. You might consider a variant similar to Promise.allSettled that catches errors and returns an array indicating success/failure (with or without stopping early on first error). For instance:

async function mapSequential(iterable, func, options) {
    const result = [];
    for (const item of iterable) {
        try {
            const value = await func(item);
            result.push({ status: "fulfilled", value });
        } catch (reason) {
            result.push({ success: "rejected", reason });
            if (options?.shortCircuit) { // Option that says "stop at first error"
                break;
            }
        }
    }
    return result;
}

Again, though, you can spin it lots of ways. Maybe add an index and the iterable to the callback like map does, perhaps have an optional thisArg (although arrow functions make that largely unnecessary these days), etc.

about 4 years ago · Juan Pablo Isaza Denunciar

0

Your forEachSequential doesn't really return anything. That's why you get undefined. When awaiting, you should attach a result to some variable, store it somewhere and then at the end of this function you should return it.

Now, you would like to return a tuple [string[], string[]]. To do so you have to create to arrays at the beginning of forEachSequential body, then call func in the loop and add a result to first array (let's say - success array) or second (failure array).

const successArray = [];
const failureArray = [];

for (let item of this) {
    const result = await func(item);

    if ('success' in result) {
        successArray.push(result.success);
    } else {
        failureArray.push(result.error);
    }
}

return [successArray, failureArray];
about 4 years ago · Juan Pablo Isaza Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda