[英]accessing value of variable outside of async/await iife
我有下面的代碼。 我需要在其他函數中使用 con 的值,但對此我沒有可能的解決方案。 我嘗試使用.thens 並像其他堆棧文章一樣等待,但我不斷收到 con 無效的錯誤。
我真的被困住了,不確定如何處理這個問題。
服務.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
});
});
}
controller.js
async function getUsers(req, res, next) {
service.getUsers().then(function(val) {
res.json(val)
});
}
得到秘密承諾
function getSecretPromise(secretName) {
return new Promise((resolve, reject) => {
client.getSecretValue({SecretId: secretName}, function(err, data)
{
//do stuff
}
}
服務.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);
});
});
});
}
您在 con 變量被返回后對其進行定義,您的 IIFE 在讀取后開始工作。 我想說的是您需要將 function 向上移動,如果這不是一個選項,那么您需要在返回之前定義 con 。 如果您已經在此 function 之前定義了它,那么我不知道。
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
});
});
}
理想情況下,您會做這樣的事情。 這將從代碼的 rest 隱藏您的實例(對於這種情況並非如此),因為您將通過 getter function 訪問它。 當然,您需要將您的秘密作為常量導入。 除非您有多個數據庫,否則將其作為參數傳遞是沒有意義的
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
});
});
});
}
通過制作 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});
});
});
}
只有這些函數應該顯式地創建新的 Promise。 這會清理connectToDatabase
function...
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)
}
}
它基本上清理了createUser
......
async function createUser({ data }) {
try {
const connection = await connectToDatabase(secretName);
let {results, fields} = query(connection, 'query');
// and so on
} catch(error) {
console.log(error);
}
}
並不是說getSecretPromise()
可能需要相同的處理,但在 OP 中並未完全指定。
其他警告:未經測試(甚至編譯)。 依賴於 scope 中的值,其定義未在 OP 中顯示(例如secretName
)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.