Skip to content

Instantly share code, notes, and snippets.

@creationix
Created December 5, 2011 19:12
Show Gist options
  • Save creationix/1434837 to your computer and use it in GitHub Desktop.
Save creationix/1434837 to your computer and use it in GitHub Desktop.
Sanity check for async template idea
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);
});
}),
<!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>
@creationix
Copy link
Author

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-104

Load 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.

@polotek
Copy link

polotek commented Dec 7, 2011

Here's another gist with some really crazy ideas :) https://gist.github.com/1439922

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment