【问题标题】:ejs async true with node Expressejs async true 与 node Express
【发布时间】:2020-05-28 21:22:58
【问题描述】:

我想调用我的一些异步函数,以便从我的 ejs 文件中调用。

就像我将此功能设置为我的app.locals.someFunction

async someFunction(param){
  let data = await someAsyncStuff();
  // &  other things
  return data;
}

我想在 ejs 文件中使用它,如下所示:

<%
let data = await someFunction()
for(let x of data){%>

   <li><%=x%></li>

<%}%>

如果 {async:true} 作为选项传递,则可以使用 ejs。但是当我的视图引擎设置如下时,我应该在哪里传递呢?


//view engine setup
app.engine ('.html', ejs.renderFile);
app.set ('view engine', 'html');

【问题讨论】:

    标签: node.js express async-await ejs


    【解决方案1】:

    对于仍在尝试弄清楚如何实现异步 ejs 模板的人,我在下面列出了我的完整解决方案:

    在您的主应用文件 (app.js) 中

    // app.js
    // Set ejs as view engine
    app.set('view engine', 'ejs');
    
    let ejsOptions = {
      // delimiter: '?', Adding this to tell you do NOT use this like I've seen in other docs, does not work for Express 4
      async: true
    };
    
    // The engine is using a callback method for async rendering
    app.engine('ejs', async (path, data, cb) => {
      try{
        let html = await ejs.renderFile(path, data, ejsOptions);
        cb(null, html);
      }catch (e){
        cb(e, '');
      }
    });
    

    现在您的路线响应...

    app.route('/login')
      .get( async (req, res) =>{
          // layout.ejs is my version of blocking. I pass the page name as an option to render custom pages in the template
          return await res.render(`layout.ejs`, { page : 'login' }, (err, html) => standardResponse(err, html, res));
    })
    
    

    我在回调中使用函数 standardResponse() 以提高可读性,因此我必须编写更少的行。函数是这样工作的……

    const standardResponse = (err, html, res) => {
      // If error, return 500 page
      if (err) {
        console.log(err);
        // Passing null to the error response to avoid infinite loops XP
        return res.status(500).render(`layout.ejs`, { page : '500', error: err }, (err, html) => standardResponse(null, html, res));
      // Otherwise return the html
      } else {
        return res.status(200).send(html);
      }
    }
    

    还有中提琴!异步ejs渲染。

    【讨论】:

      【解决方案2】:

      而不是 res.render()

      const ejs = require('ejs');
      const html = await ejs.renderFile(view, data, {async: true});
      res.send(html);
      

      每个都包含在等待中

      <body>
          <%- await include(pageView);%>
      </body>
      

      现在异步好了

      <%
      let data = await collection.find().toArray();
      
      for(let x of data){%>
      
         <li><%=x%></li>
      
      <%}%>
      

      【讨论】:

      • 是的,我就是这样做的。不过忘记发布答案了....
      【解决方案3】:

      您必须将参数 async 作为 opts 传递给您的 render() 函数调用。例如。

      res.render(view, {.., async:true, ... }...) 
      

      【讨论】:

      • 无论页面有什么,这只会将一个空的{} 作为响应。
      • 这可能是在您的模板中调用异步函数的原因。我假设您应该在渲染函数中调用该函数,而不是在模板本身中。
      • 其实项目需要在模板中调用一些函数。
      • 当文件仅包含 Hello world 时响应仍为 {},但在未传递 {async:true} 时按预期工作
      猜你喜欢
      • 1970-01-01
      • 2021-10-11
      • 2015-07-17
      • 2012-05-12
      • 1970-01-01
      • 2019-02-16
      • 1970-01-01
      • 2021-04-11
      • 2020-12-19
      相关资源
      最近更新 更多