Эффективное использование $ .when.apply (...) для пользовательских обещаний - PullRequest
0 голосов
/ 17 февраля 2020

Я использую $ .when.apply (methodArray [...]), чтобы вернуть аргументы обратного вызова метода в моем общем «готовом» обратном вызове. Это прекрасно работает, когда методы являются вызовами $. ajax (options), но иногда методы-члены являются синхронными. Я пробовал каждую комбинацию $ .Deferred, нового Promise, $ .when (). Then (...), которую я могу придумать, но я просто не могу получить данные из моего вызова syn c в отображаются в качестве аргументов в моем обратном вызове done (). Вот сокращенный пример:

var loader() {

    var obj = this;

    this.execute = function (force, success, fail) {

        if (!force) {
            var data = {message: "This is cached data"};
            if (data) {
                //this does not return data to when.apply
                return $.when().done(function () {
                    if (success) success(data);
                    return data;
                });
            }
        }
        return execute(success, fail); //this works fine
    }

    function execute(success, fail) {

        return $.ajax({
            type: obj.method,
            url: obj.url,
            data: obj.data,
            dataType: obj.dataType || "json",
            success: function (data) {
                if (obj.cacheName) setCacheData(obj.cacheName, data);
                if (obj.success) obj.success(data);
                if (success) success(data);
            },
            fail: function (err) {
                if (obj.fail) obj.fail(err);
                if (fail) fail(err);
            }
        });
    }
}

var selected = []  //array of loader objects with "execute(...)" command

$.when.apply($, $.map(selected, function (l) {
            return l.execute(force, l.success, l.fail);
        })).done(function () {
            if (success) success($.map(arguments, function (a) {
                return a[0];   //a is undefined on sync method
            }));
        }).fail(function () {
            if (fail) fail($.map(arguments, function (a) {
                return a[0];  
            }));
        });

Как правило, после первого (ajax) вызова данные кэшируются. При последующих вызовах функция «execute» будет просто получать данные из кэша вместо вызова ajax.

Как уже упоминалось, приведенный выше код when.apply отлично работает, когда команда execute выполняет вызов $. ajax. Но когда он возвращает данные, которые кэшируются (ie: из предыдущего ajax вызова), я не могу получить данные, переданные обратно в аргументах обратного вызова.

Как мне записать эту функцию «execute» в вернуть КАЖДЫЕ кэшированные данные или вызов $. ajax в качестве обещания - так, чтобы оно было прозрачным (без разницы) для «when.apply» ??

Другой способ, которым я пробовал это:

            if (data) {
                var df = $.Deferred();
                if (success) success(data);
                df.resolve(data);
                return df.promise(data);
            }

Это тоже не сработало ...

...