2

我正在尝试在 javascript 中初始化一个变量(具体来说,我想使用带有 jQ​​uery 模板插件的远程模板),然后让多个异步回调等待它在继续之前被初始化。我真正想要的是能够通过<script type="text/x-jquery-tmpl" src="/my/remote_template">标签链接到远程模板,但除非我可以摆脱与pthread_once.

理想情况下,api 看起来像:

$.once(function_to_be_called_once, function_to_be_called_after_first) 

并使用如下:

var remote_template = "";

function init_remote_template() {
    remote_template = $.get( {
        url: "/my/remote/template",
        async: false
    });
}

$.once(init_remote_template, function () {
     // Add initial things using remote template.
});

然后,在其他地方:

$.get({
    url: "/something/that/requires/an/asynchronous/callback",
    success: function () {
        $.once(init_remote_template, function () {
              // Do something using remote template.
        }
    }
});

这样的事情存在吗?

4

2 回答 2

3

看起来 jQuery 的 Promise 可以帮助你:

var templatePromise = $.get({
    url: "/my/remote/template"
});

templatePromise.done(function(template) {
     // Add initial things using remote template.
});

在其他地方你可以做:

$.get({
    url: "/something/that/requires/an/asynchronous/callback",
    success: function () {
        templatePromise.done(function(template) {
              // Do more things using remote template.
        });
    }
});

通常$.get(and$.ajax等) 在初始调用中与success:error:回调一起使用,但它们也返回一个类似于 $.Deferred 的 Promise 对象,记录在此:http ://api.jquery.com/category/deferred-object /它允许你做你所要求的。对于错误处理,您可以使用templatePromise.fail(...)或简单地添加error: ...到初始$.get.

一般来说,最好避免同步 AJAX 调用,因为大多数浏览器的接口会在处理 HTTP 请求时阻塞。

于 2013-01-04T07:05:58.767 回答
0

如果我理解正确,jQuery 将通过 Deferreds/promises 来做你想做的事。

您甚至可以通过以下方式概括远程模板提取器

  • 使用 js 普通对象来缓存任意数量的模板
  • 重命名函数并向其传递 url,get_remote_template(url)

js:

var template_cache = {};//generalised template cache

//generalised template fetcher
function get_remote_template(url) {
    var dfrd = $.Deferred();
    if(!template_cache[url]) {
        $.get(url).done(function(tpl) {
            template_cache[url] = tpl; //we use the url as a key.
            dfrd.resolve(tpl);
        });
    }
    else {
        dfrd.resolve(template_cache[url]);
    }
    return dfrd.promise();
}

然后 :

var url1 = "/my/remote/template"; //the url of a particular template

get_remote_template(url1).done(function(tpl) {
    // Add initial things using tpl.
});

而且,更早或更晚:

$.get({
    url: "/something/that/requires/an/asynchronous/callback",
    success: function(data) {
        init_remote_template(url1).done(function (tpl) {
            // Do something using tpl (and data).
        });
    }
});

注意如何get_remote_template()返回一个承诺。如果请求的模板已经被缓存,则返回的 promise 是 ready-resolved。如果模板还没有在缓存中(即需要从服务器下载),那么承诺将在短时间内解决。无论哪种方式,返回承诺的事实都允许.done()链接命令,并允许访问和使用适当的模板。

编辑

考虑到@BenAlpert 的观点,这个版本缓存了与 tpl 而不是 tpl 本身相关的承诺。

var template_cache = {};//generalised cache of promises associated with templates.

//generalised template fetcher
function get_remote_template(url) {
    if(!template_cache[url]) {
        template_cache[url] = $.get(url);
    }
    return template_cache[url];//this is a promise
}

此版本的get_remote_template()使用方式与上述相同。

于 2013-01-04T07:32:03.040 回答