jQuery $.Deferred() с динамическим URL-адресом

Я начинаю рефакторить некоторый код, чтобы использовать промисы и кэширование, чтобы обеспечить более чистый код. Мой код (см. ниже) попытался использовать эту новую предпосылку и работает с небольшим успехом. Основная проблема заключается в том, что механизм кэширования, который используется по умолчанию, не позволяет мне «передавать» значение динамического URL-адреса, не возвращая каждый раз одни и те же кэшированные результаты. Как я могу обновить приведенный ниже код, чтобы использовать ключ кеша?

"use strict";

var FLEX = window.FLEX|| {};
FLEX.Following = FLEX.Following|| {}; 

FLEX.Following.Process = function () {

var deferred = $.Deferred(),
execute = function (followUrl) {
    $.ajax(
            {
                url: _spPageContextInfo.webAbsoluteUrl +
                    followUrl,
                method: "GET",
                headers: {
                    "accept": "application/json;odata=verbose",
                },
                success: function (data) {
                    deferred.resolve(data);
                },
                error: function (err) {
                    deferred.reject(err);
                }
            }
        );
    return deferred;
};
return {
    execute: execute
}

}();

FLEX.Following.Init = function (divName, followUrl) {
FLEX.Following.Process.execute(followUrl).promise().then(

    //success
    function (data) {
        var html = "";
        $.each(data.d.Followed.results,function(index, value){
           html += value.Name + "<br />";
        });

        $(divName).html(html);

    },

    //failure
    function(err) {
        $(divName).html('Failed');
    }   
);             
}

Затем я вызываю код, используя следующие строки:

    $(document).ready(function() {
        FLEX.Following.Init("#followed-sites", "/_api/social.following/my/followed(types=4)");
        FLEX.Following.Init("#followed-people", "/_api/social.following/my/followed(types=1)");
        FLEX.Following.Init("#followed-documents", "/_api/social.following/my/followed(types=2)");     
    });

Результирующий вывод «работает», однако я получаю одинаковые результаты в каждом div, поскольку кажется, что каждый последующий вызов jQuery получает кэшированную версию из одного из них, и поэтому каждый набор результатов идентичен. Как я могу гарантировать, что я могу использовать одни и те же функции с разными динамическими URL-адресами, как указано выше, и кэшировать их отдельно.

Спасибо


person kalabo    schedule 15.09.2014    source источник


Ответы (1)


Я думаю, что основная проблема заключается в том, что вы создаете один $.Deferred(), а затем пытаетесь повторно использовать его для нескольких вызовов execute(), и это никогда не сработает. Отложенный — это однократный триггер. После того, как он был выполнен или отклонен, он остается таким и всегда содержит одни и те же данные. Если вы хотите получить другой результат для последующих вызовов, вы должны создать новый deferred для каждого вызова. Итак, поскольку вы создавали свой deferred вне функции execute(), у вас когда-либо был только один deferred, и, таким образом, первый результат просто оставался навсегда.

Исправление здесь заключается в использовании отдельного обещания/отложенного для каждого вызова execute(). Поскольку $.ajax() уже возвращает новое обещание каждый раз, когда вы его вызываете, вы можете использовать его вместо создания собственного $.Deferred вручную, что является анти-шаблоном. Давайте проведем рефакторинг и решим обе проблемы сразу.

Вот ваша функция реорганизована, поэтому решите эти проблемы:

var execute = function (followUrl) {
    return $.ajax({
         url: _spPageContextInfo.webAbsoluteUrl + followUrl,
         method: "GET",
         headers: {"accept": "application/json;odata=verbose"}
    });
};

Затем в этой строке кода:

FLEX.Following.Process.execute(followUrl).promise().then(

Вы должны удалить .promise(), потому что мое изменение выше уже возвращает обещание, поэтому эта строка может просто стать такой:

FLEX.Following.Process.execute(followUrl).then(
person jfriend00    schedule 15.09.2014
comment
Спасибо за это ... Можно ли как-то сохранить кеш и разные URL-адреса, или это просто проблема для такого рефакторинга? - person kalabo; 16.09.2014
comment
Также рефакторинг для возврата, как указано выше, не возвращает тот же объект данных, что и в предыдущем примере? это как дизайн? как мне вернуть этот объект? - person kalabo; 16.09.2014
comment
@ user257503 - вы можете удалить cache: false, если хотите. Это не имеет никакого отношения к рефакторингу. Я думал, что вы жаловались на проблему с кэшированием ваших URL-адресов, но теперь я думаю, что реальная проблема, вероятно, заключалась в том, что у вас был только один отложенный для всех URL-адресов, и мой рефакторинг исправил это, поэтому вы можете удалить строку cache, если хотите. - person jfriend00; 16.09.2014
comment
@user257503 user257503 - вам придется показать мне, какой код вы получили после рефакторинга, потому что точно такие же данные должны быть в возвращаемом обещании, которое вы вводили в свой .resolve(). Вы должны увидеть тот же результат вызова Ajax в переменной data: FLEX.Following.Process.execute(followUrl).then(function(data) { your code here}); - person jfriend00; 16.09.2014
comment
@user257503 user257503 - чтобы лучше объяснить, что, по моему мнению, происходит, я переписал объяснение в своем ответе и удалил все ссылки на проблему с кэшированием, потому что теперь, когда я лучше понимаю вашу проблему, это было не то, что на самом деле происходило. - person jfriend00; 16.09.2014