在基于Express
的应用中,我正在运行异步函数从数据库中获取图像源并将其渲染到Nunjucks
视图引擎
Nunjucks在DOM中呈现以下内容
<img src="[object Promise]">
我已经enabled Nunjucks's async rendering与web: { async: true }
和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;
});
如何获得异步函数的已解析值?
答案 0 :(得分:1)
据我了解,Nunjucks并不直接支持异步渲染。您可以使用异步过滤器来获取它。也许我错了。
Imho,使用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
}
);
答案 1 :(得分:0)
我不了解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)
})
}
这是我在文件名server.js
中的NodeJS / ExpressJS代码:
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...')
})
可以看出,我通过实施async
并且甚至没有触及视图引擎,在浏览器和服务器之间进行fetch API
通信。
我只是想提供另一种想法来使用fetch API
并与它进行async
HTTP通信,而不管正在使用的任何视图呈现引擎。