簡體   English   中英

MongoDB / EJS:如何在 EJS 中進行同步查詢和呈現結果值

[英]MongoDB / EJS: How to make synchronous query and render result values in EJS

我在異步編程的概念上有點掙扎,我希望有人能提供一些幫助/指導。 基本上,我正在開發一個連接到 mongodb 數據庫的 node.js Web 服務器。 我正在使用 EJS 生成 HTML 文件,如下所示。

app.get("/", function(req, res){
    res.render('home', {date: getData.todaysDate(), n: getData.todaysIncidents(), nTot: getData.totalIncidents()});
}); 

大多數這些值('n' 和 'nTot')是通過查詢我的數據庫然后執行一些其他操作獲得的,如下面的示例代碼示例所示。

//------getData.js------//
exports.todaysIncidents = function() {
let server_n = 0;
Incident.find({dia: {$gt:y}}, function(err, result) {
    if (err) {
        console.log(err);
    } else{
        //do some stuff...
        server_n = 12345
        }
    }
});
return server_n;

};

問題在於: HTML 文件中打印的值始終是用於變量初始化的值,例如變量 'server_n' 為 0。 在做了一些研究后,我明白這是因為 .find(...) 是一個異步函數,所以程序立即執行指令“return server_n;”,這意味着在 HTML 文件中顯示的值將是 0 和不是 12345。

我已經在 StackOverflow 中查看了其他問題,但我正在努力理解這個問題的可能解決方案,我的意思是我不可能是唯一一個經歷這個的人,對吧?

你能否提供一些關於我如何解決這個問題的基本解釋? 我仍在學習,很多這些概念仍然難以理解。

非常感謝。

是的,您是對的,問題是由於對查詢數據庫等異步操作的處理不當造成的。 那你怎么解決呢?

使用異步/等待:
在 NodeJS 中有多種處理異步操作的選項,但是,我強烈建議使用 async/await,它在語法上干凈且易於理解。
簡單來說,async/await 是一種指定和處理異步操作的方式。 使用async關鍵字指定函數是異步的,使用await關鍵字等待異步操作。 需要注意的一個關鍵事項是您只能在async函數中使用await關鍵字。 您可以在此處閱讀有關 async/await 的更多信息。
如果您的 nodeJS 版本是 7.6 或更高版本,async/await 是開箱即用的,但是,如果您使用的是較低版本且無法升級,則可以設置像Babel這樣的構建工具來使用支持的 javascript 功能在較新的 ECMAScript 規范中。

使用 async/await 時,您的代碼應該是這樣的:

//------getData.js------//
// NOTE: the typeof todaysIncidents is not more the regular function, 
// it's now an AsyncFunction because of the async keyword
exports.todaysIncidents = async function () {
  let server_n = 0;
  try {
    // In simple terms, the await keyword here would ensure that the DB query
    // resolves or reject before moving on to the next statement
    const incident = await Incident.find({ dia: { $gt: y } });
    // The incident variable stores the result of the query
    server_n = 12345
  } catch (err) {
    // Handle error from the DB query
    console.log(err);
  }
  return server_n;
};

.

//------The router------//
// NOTE: You also need to make the route handler an AsyncFunction
app.get("/", async function (req, res) {
  // You can await the differeint DB queries in here to ensure they resolve(or reject) before rendering the view
  const todaysDate = await getData.todaysDate();
  const todaysIncidents = await getData.todaysIncidents();
  const totalIncidents = await getData.totalIncidents();
  res.render('home', { date: todaysDate, n: todaysIncidents, nTot: totalIncidents });
}); 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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