使用jQuery加载promises

Mik*_*den 17 jquery promise jquery-load jquery-deferred

我仍然试图绕过我的脑袋deferred而不是,所以考虑到这一点,我有一个关于如何做以下事情的问题.

我的团队和我有3个单独的.load()方法,每个方法都抓住一个特定的模板并将其附加到同一个容器中.每个负载都会花费不同的时间,因此当内容加载时,它会以"阶梯式"方式加载(1,然后是2,然后是3).我想利用deferred物体并等到它们全部完成,然后同时附加它们以移除"阶梯"动作.

$('<div>').load(baseInfoTemplate, function () {
    var baseData = {
        // build some object
    };

    $.tmpl(this, baseData).appendTo($generalContainer);
});
Run Code Online (Sandbox Code Playgroud)

所有三个电话都与上面的电话类似.

我怎样才能做到这一点?

Rre*_*Cat 8

我为这种情况使用下一个代码:

$.when(
    $.get('templates/navbar.tmpl.html', function(data) {
        $('#navbar').html(data);
    }),
    $.get('templates/footer.tmpl.html', function(data) {
        $('#footer').html(data);
    }),
    $.Deferred(function(deferred) {
        $(deferred.resolve);
    })
).done(function() {
    $.getScript("js/tools/jquery.min.js");
});
Run Code Online (Sandbox Code Playgroud)

在我看来,它看起来比以前的实现更有条理,更漂亮.


jAn*_*ndy 6

您可以将其存储promise objects在一个数组中,并用于$.when()查明这些承诺是否已满.这看起来像这样:

var templates = [ ];

function createPromise( baseInfoTemplate ) {
    return $.Deferred(function( promise ) {
        $('<div>').load(baseInfoTemplate, function() {
            var baseData = { /* foobar */ };

            templates.push( baseData );
            promise.resolve();
        });
    }).promise();
}

var myPromises = [ ];

myPromises.push( createPromise( 'some data' ) );
myPromises.push( createPromise( 'even moar data' ) );
myPromises.push( createPromise( 'foo bar heay' ) );

$.when.apply( null, myPromises ).done( function() {
    templates.forEach(function( template ) {
        $.tmpl(this, template).appendTo($generalContainer);
    });
});
Run Code Online (Sandbox Code Playgroud)

我在.apply()这里使用,因为它接受一个数组作为函数调用的参数.基本上,我们将所有承诺对象传递给.when().

示例:http://jsfiddle.net/Hg77A/1/


更新:

正如Alnitak指出的那样,如果没有"成功"回调处理程序,上面的例子就没有多大意义.如果它足以在您传输数据后触发"全部完成"处理程序.load(),那么您只需要来自from中.resolve()的promise .这有任何意义吗?success handler.load()


Aln*_*tak 5

$.load() 不是为与 Deferred 对象一起使用而设计的,它也专门用于立即将内容放入页面中。

要解决后一个问题,您要么必须在 DOM 之外渲染整个容器,然后在它们全部完成后将其放入,或者您需要累积三个结果,然后一次性将它们全部放入。

下面的过程使用后一种方法:

  1. $.get()改为使用,并创建一个jqXHR由返回的对象组成的数组$.get()

  2. 将每个返回片段也存储$.get()在一个数组中

  3. 使用$.when.apply($, myArray).done(function() { ... })应用模板,并把它们放到DOM

http://jsfiddle.net/alnitak/WW3ja/

  • @Mike no - 你可以为每个 `$.load()` 创建一个 `$.Deferred()`,然后将 `def[n].resolve` 设置为 `$.load()` 中的完成回调。为每个模板设置一个单独的 div 也会更好。 (2认同)