Node.js SWIG 是否支持异步功能?

Node.js SWIG is it support Async function?

我有使用 Node.js 和 SWIG 模板引擎的动态 html 页面。我需要从我的 SWIG 模板调用函数以从数据库获取用户数据以呈现页面内容。 SWIG 调用函数但不等待数据库的响应。 那么,是否可以将异步函数和 return 数据调用到 swig 模板?

我的 SWIG 模板:todos.html

<body>
{%set todos=getTodos()%}
{%for item in todos%}
  <div>{{item.name}}</div>
  <div>{{item.completed}}</div>
{%endfor%}

</body>

我的节点服务器(使用 express):

.......
swig.setDefaults({locals:{getTodos:function(input){
       setTimeout(function(){
        return [
                {name:"First todo",completed:false},
                {name:"Same name",completed:true},
               ]
       },5000)
    })
........

但是页面没有等待来自 "timeout" 的数据就呈现了。

所以基本上不行,你不能直接在模板中使用异步函数。不支持。

但是你仍然可以做你想做的事,只需先异步获取你需要的所有数据,然后渲染 swig 模板。

这是最简单的例子:

const swig = require('swig');
const express = require('express');

const app = express();

const swigEngine = new swig.Swig();
app.engine('html', swigEngine.renderFile);
app.set('view engine', 'html');

const loadTodos = function (callback) {
    setTimeout(function () {
        const todos = [
            {name: "First todo", completed: false},
            {name: "Same name", completed: true},
        ];

        callback(null, todos);
    }, 1000)
};

app.get('/', (req, res) => {
    // So first you get the data asynchronously 
    loadTodos(function (err, data) {
        if (err) {
            res.sendStatus(400);
            return;
        }
        
        res.render('index', {todos: data});
    })
});

app.listen(5555, () => console.log('Server is running on port 5555.'))

如果你这样做,你的模板也会变得更简单:

{%for item in todos%}
 <!-- You have missed the curly brackets here {{}} -->
 <div>{{item.name}}</div>
 <div>{{item.completed}}</div>
{%endfor%}