akdubya / dustjs

Asynchronous templates for the browser and node.js
http://akdubya.github.com/dustjs/
MIT License
1.44k stars 131 forks source link

The callback interface is not always suitable #65

Open thany opened 11 years ago

thany commented 11 years ago

It needs an option to return the result of a template. I'm currently working with another plugin that has a callback of its own, and in that callback I must return a jQuery object or a blob of html for it to further process. That mean I have to immediately return something, I cannot tell it to wait for an arbitrary second callback.

Currently I have to hack my way around this, which is FUGLY, and since a template usually does nothing that's asynchronous, having the render-function return the template result would be most preferable.

thany commented 11 years ago

This sort of works:

var frag = document.createDocumentFragment();
dust.render("listing-template", item, function(err, out) {
  $(frag).append(out);
});
return frag;

When some callback requires that content is returned. See why I said "hack my way around"? This is ugly and feels like a nice oldskool hack, which is not what I want in production code. It is a good thing that in this particular case the callback doesn't require a string to be returned, and I could get away with a doc fragment.

brianblocker commented 11 years ago

I believe that this may have something to do with Node compatibility, since the author appears to be following nodes "non-blocking" convention of an err as the first param of the callback. Also the asynchronous nature of it may play a part. Would definitely love to see an option for this though.

thany commented 11 years ago

Why not both?

jimmyhchan commented 11 years ago

Pre-compile the templates and include it in your page (as a script include or whatever dependency manager) before you call dust.render. You know it is available if dust.cache['myTemplateName'] is exists.

This issue was discussed very recently at https:///github.com/linkedin/dustjs/.

thany commented 11 years ago

Precompilation is not nearly always an option. I have to deal with archaic CMS systems, and there's just no way that precompiling is ever going to be part of their build-process. Don't ask, it's just the way it is. Manually performing another step in the build process is asking for problems, so no, precompilation isn't going to cut the mustard.

jimmyhchan commented 11 years ago

You'll want to look into async management Something with Promise or react to events that are fired. jQuery deferreds may be what you want.

There was some talk in the LinkedIn fork to allow users to require sync render even if it has to fetch and compile the code client side. It's not performant in many ways and client-side async management libraries exist, so it got very deprioritized.

sethkinast commented 9 years ago

So compiling is always synch. That's safe.

You're also safe to do something like this:

var str;
dust.render(tmpl, ctx, function(err, out) { str = out; });
return str; // str is populated

UNLESS you do one of the following things:

We'd like Dust to return Promises but it's not worth adding a dependency. Someday Promises will be native in all browsers and we'll handle it then. Until then, you can wire up your own Promise and resolve it in the callback, or use the pseudosync behavior above (which releases Zalgo but eh).