使用Dynamic Url的jQuery $ .Deferred()

时间:2014-09-15 20:17:41

标签: javascript jquery caching promise

我开始重新考虑一些代码以使用promises和缓存来确保更清晰的代码。我的代码(见下文)试图使用这个新的前提,并取得了一些成功。主要问题是默认情况下使用的缓存机制阻止我无法在动态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相同的功能并单独缓存它们。

谢谢

1 个答案:

答案 0 :(得分:2)

我认为根本问题是您创建了一个$.Deferred(),然后您尝试将其重复用于多次调用execute(),这将无法正常工作。延迟是一次触发。一旦完成或被拒绝,它就会保持这种状态并永远包含相同的数据。如果您希望在后续呼叫中获得不同的结果,则必须为每个呼叫创建一个新的延迟。所以,因为你在execute()函数之外创建了延迟,所以你只有一个延迟,因此第一个结果将永远坚持下去。

此处的修复是对每次execute()的调用使用单独的promise / deferred。由于$.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(