Created
December 5, 2011 19:12
-
-
Save creationix/1434837 to your computer and use it in GitHub Desktop.
Sanity check for async template idea
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Creationix.route("GET", "/", function (req, res, params, next) { | |
render("frontindex", { | |
title: query("index", "title"), | |
links: query("index", "links"), | |
articles: loadArticles | |
}, function (err, html) { | |
if (err) return next(err); | |
res.writeHead(200, { | |
"Content-Length": Buffer.byteLength(html), | |
"Content-Type": "text/html; charset=utf-8" | |
}); | |
res.end(html); | |
}); | |
}), |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html> | |
<head> | |
<title>@title()</title> | |
<link rel="stylesheet" href="style.css"/> | |
</head> | |
<body> | |
@render("topbar", this) | |
<div class="container_16"> | |
<div class="grid_11"> | |
<div class="section">@render("summary", articles)</div> | |
</div> | |
<div class="grid_5"> | |
<div class="section">Sidebar</div> | |
</div> | |
</div> | |
@render("footer", this) | |
</body> | |
</html> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I realise that I didn't show enough code in this example. The full query for loadArticles can be found at https://github.com/c9/nog/blob/master/server.js#L53-85.
query()
is just a simple helper that does a db query and returns the result in a callback. If you don't provide a callback in the first call, it returns a curried version of itself. https://github.com/c9/nog/blob/master/server.js#L100-104Load Articles does several manual db joins to gather the data. It is hand written async code and runs as much parallel as possible, but clearly I can't load the author's file without first loading the article's metadata to know who the author is.
So I think there are two kinds of async logic in rendering a view. The first is to know what page to render. This is decision logic and shouldn't be embedded in a view. Usually the url tells enough that we know right away what to load, but this might not always be the case. The second kind of logic is, once we know what to do, we need to gather and load all the required data.
This is the part I propose the view handle for us. For complicated things like "loading a listing of article ids and then loading those articles in parallel and loading the author data for each article as the author name is known" I still think hand-written code is fine. Nested async code is quite nice and efficient in small amounts.
Caching, batching, and request pooling can integrate very nicely with this model and should be for anything that involved real resources like file descriptors or 500 concurrent requests for the same page will crash your server.
Thanks everyone for the input! Keep it coming.