Tengo el código a continuación. Necesito usar el valor de con en otras funciones, pero no tengo una solución posible para esto. Intenté usar .thens y awaits como otros artículos de la pila, pero seguí recibiendo el error de que la estafa no es válida.
Estoy realmente atascado y no estoy seguro de cómo manejar esto.
servicio.js
async function connectToDatabase(secret) { try { const secretValue = await getSecretPromise(secret) const { host, port, username, password, dbname } = JSON.parse(secretValue); let con = mysql.createConnection({ host: host, port: port, user: username, password: password, database: dbname }); con.connect(function(err) { if (err) throw err; console.log("Connected to database!"); }); return con; } catch (error) { console.error(error) } } // Start an IIFE to use `await` at the top level (async function(){ let con = await connectToDatabase(secretName); })(); function createUser({ data }) { return new Promise((resolve, reject) => { var sql = `query`; con.query(sql, function (err, result) { //does not work currently because ReferenceError: con is not defined }); }); }controlador.js
async function getUsers(req, res, next) { service.getUsers().then(function(val) { res.json(val) }); }conseguirsecretpromesa
function getSecretPromise(secretName) { return new Promise((resolve, reject) => { client.getSecretValue({SecretId: secretName}, function(err, data) { //do stuff } }servicio.getUsers
//this is in service.js module.exports = { createUser, getUsers, patchUser, loginUser, updateCallForward, getEmail, getCallForwardingNumber, getDB }; function getUsers() { return new Promise((resolve, reject) => { var sql = `sql`; getDB().then(con => { con.query(sql, function (err, result) { if (err) throw err; resolve(result); }); }); }); }El código se puede simplificar (y reparar) haciendo versiones de retorno de promesa de las funciones de estilo de devolución de llamada de mysql...
async function connect(connection) { return new Promise((resolve, reject) => { connection.connect(function (err) { err ? reject(err) : resolve(connection) }); }) } async function query(connection, query) { return new Promise((resolve, reject) => { connection.query(query, function (err, results, fields) { err ? reject(err) : resolve({results, fields}); }); }); } Solo estas funciones deberían crear nuevas promesas explícitamente. Esto limpia la función connectToDatabase ...
async function connectToDatabase(secret) { try { const secretValue = await getSecretPromise(secret) const { host, port, username, password, dbname } = JSON.parse(secretValue); let con = mysql.createConnection({ host: host, port: port, user: username, password: password, database: dbname }); return await connect(con); } catch (error) { console.error(error) } } Y limpia createUser sustancialmente...
async function createUser({ data }) { try { const connection = await connectToDatabase(secretName); let {results, fields} = query(connection, 'query'); // and so on } catch(error) { console.log(error); } } No es que getSecretPromise() pueda requerir el mismo tratamiento, pero no está completamente especificado en el OP.
Otras advertencias: no probado (o incluso compilado). Se basa en valores en el alcance cuyas definiciones no se muestran en el OP (por ejemplo secretName ).
Está definiendo la variable con después de que se devuelva, su IIFE comienza a funcionar una vez que se lee. Lo que estoy tratando de decir es que debe mover esa función hacia arriba y, si esa no es una opción, debe definir con antes de devolverla. Si ya lo definiste antes de esta función, entonces no lo sé.
async function connectToDatabase(secret) { // Start an IIFE to use `await` at the top level (async function(){ let con = await connectToDatabase(secretName); })(); try { const secretValue = await getSecretPromise(secret) const { host, port, username, password, dbname } = JSON.parse(secretValue); let con = mysql.createConnection({ host: host, port: port, user: username, password: password, database: dbname }); con.connect(function(err) { if (err) throw err; console.log("Connected to database!"); }); return con; } catch (error) { console.error(error) } } function createUser({ data }) { return new Promise((resolve, reject) => { var sql = `query`; con.query(sql, function (err, result) { //does not work currently because ReferenceError: con is not defined }); }); }Idealmente harías algo como esto. Esto ocultaría su instancia (no realmente para este caso) del resto del código, ya que accederá a él a través de una función getter. Por supuesto, necesita importar su secreto como una constante. No tiene sentido pasarlo como parámetro a menos que tenga varios dbs
let con = null; async function connectToDatabase(secret) { try { const secretValue = await getSecretPromise(secret) const { host, port, username, password, dbname } = JSON.parse(secretValue); con = mysql.createConnection({ host: host, port: port, user: username, password: password, database: dbname }); con.connect(function (err) { if (err) throw err; console.log("Connected to database!"); }); return con; } catch (error) { console.error(error) con = null; } } export async function getDB() { if (con == null) { let secretObj = {}; return await connectToDatabase(secretObj); } else { return Promise.resolve(con); } } export function createUser({ data }) { return new Promise((resolve, reject) => { var sql = `query`; getDB().then(con => { con.query(sql, function (err, result) { //does not work currently because ReferenceError: con is not defined }); }); }); }