问题
I have a collection containing different URLs of images. I retrieve the URL I want and want to pass it to the jade template like:
app.get('/',function(req,res){
mongoDB.getUsedHomePageOne(function(err, result){
if(!err){
console.log("getUsedHomePageOne : ");
console.log(result);
app.locals['homePageImg'] = result.url;
}
});
app.render('userPageEjs.html',function(err,renderedData){
console.log(renderedData);
res.send(renderedData);
});
});
and the getUsedHomePageOne looks like:
DBMongo.prototype.getUsedHomePageOne = function(callback){
this.homePageColl.findOne({used:1}, callback);
};
and in the jade template:
<img src="<%= homePageImg %>"/>
So this won't work except if I load twice the page, I assume because it gets cached and is computed quickly enough or something.
What is the proper way of doing it?
PS: the 2nd time I load the page, everything will load correctly.
PS2: I don't want to delay the rendering for the image, I would like to load the image once it is ready, but render the HTML page before anyway.
回答1:
From what I've gathered in your code:
app.get('/',function(req,res){
mongoDB.getUsedHomePageOne(function(err, result){
if(!err){
console.log("getUsedHomePageOne : ");
console.log(result);
app.locals['homePageImg'] = result.url;
app.render('userPageEjs.html',function(err,renderedData){
console.log(renderedData);
res.send(renderedData);
});
}
});
});
Basically, you have an async function to the DB and you quickly render the template before waiting for the DB function to complete. The normal pattern when using async functions whose results should be used down the line, you have to call the next function inside the async function. However, this might lead to callback hell (similar to how I've written the fix above), so an alternative like Promises or async.js is usually preferred.
来源:https://stackoverflow.com/questions/30963743/display-dynamically-an-image-using-express-and-ejs