簡體   English   中英

訪問 async/await iife 之外的變量值

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM