Q:

How to return templates from cache or ajax load? 

In my code I try to load templates from cache.  If template does not present in cache - load template from server by ajax.  When loading is finished, I want to put template to cache and return it.  Here is it:
var manager = function () {

    return {

        cache: [],
        getTemplate: function (templateId) {

            this.templateId = templateId;

            if (this.cache[this.templateId]) {
                return this.cache[this.templateId];
            }

            return this.loadTemplate();
        },

        loadTemplate: function() {

            var
            self = this;

            $.get('/assets/templates/' + this.templateId + '.html', function (templateHtml) {

                self.cache[self.templateId] = templateHtml;
                return self.getTemplate(self.templateId);
            });
        }
    }
}

var
manager = manager();

$('body').append( manager.getTemplate('template') );

I know that my code does not working because ajax request finished after function loadTemplate end.  I think code can be fixed with deferred object but don't know how.  Can anyone help me to find a solution? 

A:

There are two way of achieving your goal:

Promises (there are a lot of libs/shims).  I'll rewrite it to ES6 just for the learning: 
let manager = function () {

    return {

        cache: [],

        getTemplate(id) {
            let cache = this.cache;

            return new Promise((resolve, reject) => {
                if (cache[id]) {
                    resolve(cache[id]);
                } else {
                    this.loadTemplate(id)
                        .then(template => {
                            cache[id] = template;
                            resolve(template);
                        })
                        .fail(reject);
                }
            });
        },

        loadTemplate(id) {
            return $.get('/assets/templates/' + id + '.html');
        }
    }
};

let manager = manager();

manager.getTemplate('template').then((template) => {
    $('body').append(template);
});

Callbacks:
let manager = function () {

    return {

        cache: [],

        getTemplate(id, cb) {
            let cache = this.cache;

            if (cache[id]) {
                cb(cache[id]);
            } else {
                this.loadTemplate(id)
                    .then(template => {
                        cache[id] = template;
                        cb(template);
                    });
            }
        },

        loadTemplate(id) {
            return $.get('/assets/templates/' + id + '.html');
        }
    }
};

let manager = manager();

manager.getTemplate('template', (template) => {
    $('body').append(template);
});

