es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

Nodo y async: ¿Por qué no se está respetando el await en una subfunción?

Soy un estudiante de Node.js y estoy escribiendo un breve ejemplo. La solicitud en /org funciona como se espera.

Con la solicitud en /orgg, intenté separar la lógica de “obtener los datos” del controlador. Sin embargo, getRowsAsync() devuelve inmediatamente una Promesa.

No es bueno poner el “await en express.get()” para ocultar la lógica. Si mi lógica comercial necesita algunas Promesas secuenciales, entonces la lógica comercial tendría que propagarse hasta el controlador.

¿Cómo puedo hacer el equivalente a llamar a “doBizLogic()” en el controlador, ocultando mis awaits y haciendo que el controlador espere a que se complete la lógica? ¿Debo pasar una función de devolución de llamada a la lógica comercial para que este esquema funcione?

Aquí está mi index.js. Omite database.js, pero lo tomé prestado de https://mhagemann.medium.com/create-a-mysql-database-middleware-with-node-js-8-and-async-await-6984a09d49f4

const express = require("express");
const urlPort = 3000;
let app = express();
let mysql = require("mysql2");
let pool = require("./database");

app.listen(urlPort, () => {
  console.log("El servidor se está ejecutando en el puerto " + urlPort);
});

app.get("/", (req, res) => {
  res.send("Esta aplicación responde solo a /org y /org/:id.");
});

app.get("/org", async (req, res) => {
  let rows = await getRows("select * from org");
  // el console.log siempre imprime un array JSON.
  console.log("en app.get para /org, filas: ", rows);
  res.send(rows);
});

app.get("/orgg", (req, res) => {
  let rows = getRowsAsync();
  // el console.log() imprime inmediatamente una Promesa.
  console.log("en app.get para /orgg, filas: ", rows);
  res.send(rows);
});

function getRows(sql, params = []) {
  let rows = pool.query(sql, params);
  // el console.log() imprime una Promesa.
  console.log("en getRows, filas: ", rows); // devuelve 
  return rows;
}

async function getRowsAsync() {
  let rows = await getRows("select * from org");
  // el console.log() imprime un array JSON, una vez que se llama finalmente.
  console.log("en getRowsAsync, filas: ", rows);
  return rows;
}

Tags:  , , ,

Answer

  1. Avatar for davy.ai

    Como experto en tecnología de la información especializado en javascript, node.js, express y async-await, recomendaría utilizar async/await en el controlador para esperar a que la lógica se complete. Para lograr esto, puedes modificar la función app.get() de la siguiente manera:

    app.get("/orgg", async (req, res) => {
      let rows = await getRowsAsync();
      console.log("en app.get para /orgg, filas: ", rows);
      res.send(rows);
    });
    

    Al agregar la palabra clave ‘async’ antes de la función, puedes agregar la palabra clave ‘await’ antes de llamar a la función asíncrona, y el controlador esperará a que la lógica se complete antes de continuar.

    No es necesario pasar una función de devolución de llamada a la lógica empresarial para que este esquema funcione. También puedes utilizar el mismo patrón de diseño async/await en la lógica empresarial y asegurarte de que devuelva una Promesa.

    En general, la solución consiste en simplemente modificar la función app.get() en el controlador agregando la palabra clave ‘async’ y utilizar la palabra clave ‘await’ antes de llamar a la función asíncrona. De esta manera, el controlador esperará a que se resuelva la promesa y la lógica se completará antes de que el controlador continúe.

Comments are closed.