使用 Keystone View 进行 Nunjucks 异步渲染
Nunjucks Async Rendering with Keystone View
在基于 Express
的应用程序中,我是 运行 一个异步函数,用于从数据库中获取图像源并将它们渲染到 Nunjucks
视图引擎中
Nunjucks 正在 DOM
中呈现以下内容
<img src="[object Promise]">
我已经enabled Nunjucks's async rendering with web: { async: true }
and enabled the nunjucks async api with a callback喜欢
// controller.js (KeystoneJS app)
view.render('index', function (err, res) {
console.log('err at index render', err); // undefined
return res;
});
如何获取异步函数的解析值?
据我了解,Nunjucks 不直接支持异步渲染。您可以使用异步过滤器来获取它。也许我错了。
恕我直言,使用带有 Be Careful!
标记的功能不是个好主意。
// template.njk
Hello {{user_id | find | attr('name') }}!
// app.js
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
// Async filter
env.addFilter('find', function(a, cb) {
setTimeout(function () {
cb(null, {
name: 'Smith'
});
}, 10);
}, true)
// Sync filter
env.addFilter('attr', function(obj, attr) {
return obj && attr && obj[attr];
});
env.render('template.njk',
{user_id: 1}, // pass sync vars
function(err, res) {
if (err)
return;
console.log(res);
return res
}
);
我不知道 nunjucks
,但无论使用何种视图引擎,您都可以实现 async
功能。为了展示这个想法,我试着重现你的情况。我创建了一个名为 index.html
的 HTML 文件,带有 img
标签,没有任何 src
属性:
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Reproduce</title>
</head>
<body>
<img id='bg'></img>
<script src='./so.js'></script>
</body>
</html>
我的 HTML 中有一个 <script>
标签,它链接到我的 so.js
文件,如下所示,通过向 NodeJS/Express 发送 HTTP 请求来请求图像服务器:
getImage();
function getImage(){
// Get an image by its name as URL parameter
fetch('/bg/background.jpg',{
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}).then(result=>{
return result.blob()
}).then(result=>{
console.log('result -> ', result)
document.querySelector('#bg').src=URL.createObjectURL(result)
document.querySelector('#bg').style.width='200px'
}).catch(err=>{
console.log('err -> ', err)
})
}
这是我的NodeJS/ExpressJS代码里面的一个文件名server.js
:
express=require('express')
bodyParser=require('body-parser')
path=require('path')
fetch=require('node-fetch')
server=express()
//Body-parser middleware
server.use(bodyParser.json())
server.use(bodyParser.urlencoded({extended:false}))
server.use(bodyParser.raw())
//Set static path
server.use(express.static(path.join(__dirname,'public')))
server.get('/',(req,res)=>{
res.render('index.html')
})
// Pick a file on hard disk
// and send it as "Blob" to the browser
server.get('/bg/:name',(req,res)=>{
var options = {
root: __dirname + '/public/',
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
var fileName = req.params.name;
res.sendFile(fileName, options, function (err) {
if (err) {
next(err);
} else {
console.log('Sent:', fileName);
}
});
})
server.listen('8000',()=>{
console.log('Server listening on port 8000...')
})
如您所见,我通过实现 fetch API
在浏览器和服务器之间进行 async
通信,甚至没有接触视图引擎。
我只是想提供一个替代想法 使用 fetch API
并与它进行 async
HTTP 通信,而不管任何视图渲染引擎是正在使用。
在基于 Express
的应用程序中,我是 运行 一个异步函数,用于从数据库中获取图像源并将它们渲染到 Nunjucks
视图引擎中
Nunjucks 正在 DOM
中呈现以下内容<img src="[object Promise]">
我已经enabled Nunjucks's async rendering with web: { async: true }
and enabled the nunjucks async api with a callback喜欢
// controller.js (KeystoneJS app)
view.render('index', function (err, res) {
console.log('err at index render', err); // undefined
return res;
});
如何获取异步函数的解析值?
据我了解,Nunjucks 不直接支持异步渲染。您可以使用异步过滤器来获取它。也许我错了。
恕我直言,使用带有 Be Careful!
标记的功能不是个好主意。
// template.njk
Hello {{user_id | find | attr('name') }}!
// app.js
var nunjucks = require('nunjucks');
var env = nunjucks.configure();
// Async filter
env.addFilter('find', function(a, cb) {
setTimeout(function () {
cb(null, {
name: 'Smith'
});
}, 10);
}, true)
// Sync filter
env.addFilter('attr', function(obj, attr) {
return obj && attr && obj[attr];
});
env.render('template.njk',
{user_id: 1}, // pass sync vars
function(err, res) {
if (err)
return;
console.log(res);
return res
}
);
我不知道 nunjucks
,但无论使用何种视图引擎,您都可以实现 async
功能。为了展示这个想法,我试着重现你的情况。我创建了一个名为 index.html
的 HTML 文件,带有 img
标签,没有任何 src
属性:
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge"/>
<title>Reproduce</title>
</head>
<body>
<img id='bg'></img>
<script src='./so.js'></script>
</body>
</html>
我的 HTML 中有一个 <script>
标签,它链接到我的 so.js
文件,如下所示,通过向 NodeJS/Express 发送 HTTP 请求来请求图像服务器:
getImage();
function getImage(){
// Get an image by its name as URL parameter
fetch('/bg/background.jpg',{
method: 'GET',
headers: {
'Content-Type': 'application/json'
}
}).then(result=>{
return result.blob()
}).then(result=>{
console.log('result -> ', result)
document.querySelector('#bg').src=URL.createObjectURL(result)
document.querySelector('#bg').style.width='200px'
}).catch(err=>{
console.log('err -> ', err)
})
}
这是我的NodeJS/ExpressJS代码里面的一个文件名server.js
:
express=require('express')
bodyParser=require('body-parser')
path=require('path')
fetch=require('node-fetch')
server=express()
//Body-parser middleware
server.use(bodyParser.json())
server.use(bodyParser.urlencoded({extended:false}))
server.use(bodyParser.raw())
//Set static path
server.use(express.static(path.join(__dirname,'public')))
server.get('/',(req,res)=>{
res.render('index.html')
})
// Pick a file on hard disk
// and send it as "Blob" to the browser
server.get('/bg/:name',(req,res)=>{
var options = {
root: __dirname + '/public/',
dotfiles: 'deny',
headers: {
'x-timestamp': Date.now(),
'x-sent': true
}
};
var fileName = req.params.name;
res.sendFile(fileName, options, function (err) {
if (err) {
next(err);
} else {
console.log('Sent:', fileName);
}
});
})
server.listen('8000',()=>{
console.log('Server listening on port 8000...')
})
如您所见,我通过实现 fetch API
在浏览器和服务器之间进行 async
通信,甚至没有接触视图引擎。
我只是想提供一个替代想法 使用 fetch API
并与它进行 async
HTTP 通信,而不管任何视图渲染引擎是正在使用。