javascript是否相当于`pthread_once`

时间:2013-01-04 06:30:08

标签: javascript jquery synchronization

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

理想情况下,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.
        }
    }
});

这样的事情存在吗?

2 个答案:

答案 0 :(得分:3)

看起来jQuery的承诺可以帮到你:

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(和$.ajax等)在初始调用中与success:error:回调一起使用,但它们也会返回一个类似于a。延期,在此处记录:http://api.jquery.com/category/deferred-object/,它允许您执行您要求的操作。对于错误处理,您可以使用templatePromise.fail(...)或只是将error: ...添加到初始$.get

一般情况下,最好避免同步AJAX调用,因为大多数浏览器都是如此。在处理HTTP请求时,接口将阻塞。

答案 1 :(得分:0)

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

您甚至可以通过

来概括远程模板提取器
  • 使用js plain对象来缓存任意数量的模板
  • 重命名该函数并将网址传递给它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的事实都允许链接.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()将以与上述相同的方式使用。