Использование загрузки jQuery с обещаниями

Я все еще пытаюсь осмыслить deferred и все остальное, поэтому помня об этом, я есть вопрос, как сделать следующее.

У меня и моей команды есть 3 отдельных метода .load () , каждый из которых берет определенный шаблон и добавляет его в один и тот же контейнер. Каждая загрузка занимает разное время, как вы могли подумать, поэтому, когда контент загружается, он загружается «ступенчато» (1, затем 2, затем 3). Я хотел бы использовать отложенные объекты и подождать, пока они все не будут выполнены, а затем добавить их одновременно, чтобы удалить действие «ступенька».

$('
').load(baseInfoTemplate, function () { var baseData = { // build some object }; $.tmpl(this, baseData).appendTo($generalContainer); });

Все три вызова являются аналогично вызову выше.

Как я могу этого добиться?

17
задан Chait 27 February 2017 в 22:48
поделиться

2 ответа

Вы можете сохранить 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);
    });
});

Я использую здесь .apply(), потому что он принимает массив в качестве аргументов для вызова функции. В общем, мы передаем все объекты обещания .when().

Пример : http://jsfiddle.net/Hg77A/1/


Обновление:

, как указал Альнитак Приведенный выше пример не будет иметь большого смысла, если не будет обработчика обратного вызова «success». Если достаточно просто запустить обработчик «все сделано» после передачи данных с помощью .load(), вам просто нужно .resolve() обещания в пределах success handler из .load(). Имеет ли это какой-то смысл?

6
ответ дан 30 November 2019 в 13:38
поделиться

Вот Gist для небольшого плагина jQuery, который добавляет функцию loadThen к набору элементов jQuery. Это в основном load () без обратного вызова и возвращает обещание, которое разрешается только после того, как контент загружен и вставлен в набор выбранных элементов.

Это в основном копирование / вставка собственного кода load () jQuery, за исключением того, что он возвращает обещание от фактического вызова ajax. Это позволяет вам получить отклоненное обещание в случае сбоя ajax.

Поскольку он основан на функциональности load (), вы можете добавить селектор после URL, разделенного пробелом, чтобы получить только фрагмент загруженного html.


Пример 1: Загрузить домашнюю страницу этого сайта в элемент с id = "container"

$('#container').loadThen('/').then(function () {
    // loaded and ready.
}, function () {
    // error
});

Пример 2: Загрузить Заголовок домашней страницы в заголовок этой страницы

$('h1').eq(0).loadThen('/ h1').then(function () {
    // loaded and ready.
}, function () {
    // error
});

Содержание:

(function ($) {
    var _loadThen = $.fn.loadThen;
    $.fn.loadThen = function (url, params) {
        if (typeof url !== "string" && _loadThen) {
            return _loadThen.apply(this, arguments);
        }

        if(this.length <= 0) {
            return jQuery.Deferred().resolveWith(this, ['']);
        }

        var selector, type, response,
            self = this,
            off = url.indexOf(" ");

        if (off >= 0) {
            selector = jQuery.trim(url.slice(off));
            url = url.slice(0, off);
        }

        if (params && typeof params === "object") {
            type = "POST";
        }

        return jQuery.ajax({
            url: url,
            type: type,
            dataType: "html",
            data: params
        }).then(function (responseText) {
                self.html(selector ? jQuery("<div>").append(jQuery.parseHTML(responseText)).find(selector) : responseText);
            return self;
        });
    };
}(jQuery));
1
ответ дан 30 November 2019 в 13:38
поделиться
Другие вопросы по тегам:

Похожие вопросы: