Tengo una función queryDatabase() en mi aplicación nodeJS, que es responsable de consultar una base de datos Azure SQL y devolver el resultado, usando la biblioteca Tedious para conectarme a la base de datos.
Actualmente, para devolver los datos recuperados de la base de datos, estoy iterando a través de las filas devueltas por la consulta, guardando los datos en una var (una matriz de dictados, en realidad JSON) y devolviéndolos. Sin embargo, estoy experimentando un problema en el que se devuelve el var (vacío) antes de que se le pueda asignar algo.
Estoy bastante seguro de que esto tendría algo que ver con las funciones de devolución de llamada en request.on() que se ejecutan después de que se llama la devolución, pero soy un poco inexperto con este lado de JS y no he tenido mucha suerte con la documentación en línea/ tutoriales
function queryDatabase(){ console.log("Reading rows from the Table..."); // Read all rows from table const request = new Request( `select TOP 5 level, city, address from [dbo].[mainTable];`, (err, rowCount) => { if (err) { console.error(err.message); } } ); var result = []; request.on("row", (columns) => { var entry = {}; columns.forEach((column) => { entry[column.metadata.colName] = column.value; }); result.push(entry); }); connection.execSql(request); return result; }Cualquier ayuda sería muy apreciada, saludos!
La Request es un emisor de eventos, por lo que se trata de esperar a que sucedan todos los eventos que le interesan y luego devolver el resultado. Para eso están los Promise . Una promesa es una acción asíncrona que se resolverá en una fecha futura. debe esperar a que se emitan todos los eventos de row , recopilarlos, luego esperar el evento done y resolver la promesa. Modifiqué su código para lograr esto y mostré un ejemplo de uso.
function queryDatabase(){ console.log("Reading rows from the Table..."); // Read all rows from table const request = new Request( `select TOP 5 level, city, address from [dbo].[mainTable];`, (err, rowCount) => { if (err) { console.error(err.message); } } ); return new Promise((resolve,reject)=>{ const result = []; request.on("row", (columns) => { const entry = {}; columns.forEach((column) => { entry[column.metadata.colName] = column.value; }); result.push(entry); }); request.on('error',error=>reject(error));// some error happened, reject the promise request.on('done',()=>resolve(result)); // resolve the promise with the result rows. connection.execSql(request); }); }Uso que se muestra a continuación:
queryDatabase().then(rows=>{ // do something with the rows }) .catch(error=>{ // do something with the error })La respuesta de @ r3wt es correcta, pero esta funcionó para mí:
request.on("doneProc", () => resolve(result));En vez de
request.on('done',()=>resolve(result));