A continuación, pegué el código PoC, donde eliminé muchas líneas, pero muestra el problema/pregunta al que me enfrento.
createPost() devuelve un "número de publicación" en la variable ret . No necesito el "número de publicación para nada más que registrarlo.
Con la implementación actual, tengo que definir ret fuera del ciclo while , y dado que el código secuencial se ejecuta antes que el código asíncrono en el ciclo de eventos de NodeJS, espero que el registro se ejecute antes createPost() , que no es lo que quiero.
Pregunta
¿Es posible iniciar sesión solo cuando se ha ejecutado ret createPost() ?
module.exports = async (p) => { let ret = 0; try { while (true) { switch (x) { case 1: isOk = await getStatusCode({ ... }); break case 2: isOk = await getString({ ... }); break default: throw ""; }; ret = await createPost(p); appLogger.info(`Created post: ${ret}`); // I don't need 'ret' for anything else than logging it } catch (error) { appLogger.error(error); } }createPost.js
const axios = require('axios'); module.exports = async (c) => { try { const r = await axios({ ... }); return r.data.key; } catch (error) { throw new Error(JSON.stringify(error.response.data, null, 2)); }; };... y dado que el código secuencial se ejecuta antes que el código asíncrono en el bucle de eventos de NodeJS, espero que el registro se ejecute antes de createPost(), que no es lo que quiero.
Todo el código en una función async después de la primera await es asíncrono, no síncrono. En su código, la llamada appLogger.info no ocurrirá hasta createPost haya terminado su trabajo (asincrónicamente).
Por lo tanto, no es necesario declarar ret fuera del ciclo (e incluso si lo anterior no fuera cierto, eso realmente no ayudaría), puede hacerlo en línea, vea los comentarios *** :
module.exports = async (p) => { // *** No `ret` here try { while (true) { switch (x) { case 1: isOk = await getStatusCode({ ... }); break case 2: isOk = await getString({ ... }); break default: throw ""; }; const ret = await createPost(p); // *** Declare it here appLogger.info(`Created post: ${ret}`); } catch (error) { appLogger.error(error); } } El código espera, de forma asincrónica, en await y solo continúa cuando se realiza createPost .
He aquí un ejemplo simplificado:
const randomDelay = () => new Promise(resolve => { setTimeout(resolve, Math.floor(Math.random() * Math.floor(Math.random() * 300) + 500)); }); async function doSomethingElse() { await randomDelay(); } async function createPost(i) { await randomDelay(); return i * 2; } async function example(max) { console.log("Starting (this log is synchronous)"); for (let i = 0; i < max; ++i) { await doSomethingElse(); const ret = await createPost(i); console.log(`i = ${i}, ret = ${ret}`); } console.log("All done"); } console.log("Calling example"); example(5) .then(() => { console.log("example promise fulfilled"); }) .catch(error => { console.error("example promise rejected", error); }); console.log("Done calling example, it's running asynchronously"); Técnicamente , no necesitas ret en absoluto, esto también funcionaría:
appLogger.info(`Created post: ${await createPost(p)}`);pero si fuera yo, lo mantendría como se muestra en el primer bloque de código anterior. Es más fácil de depurar.