如何避免手动缓存返回错误的请求



我创建了一个模块(遵循Javascript的模块模式(,它发出http请求,缓存并返回结果:

var requestService = (function($) {
    var cache = {};
    var get = function(date) {
        var params = date ? {'date': date} : {};
        return $.getJSON('http://my/url', params, function( result ){});
    };
    var fetchData = function(date) {
        if (!cache[date]) {
            cache[date] = get(date);
        }
        return cache[date].done(function(myData) {
            return new Promise(function(resolve,reject) {
                resolve(myData);
            });
        });
    };
    return {
        fetchData: fetchData
    };
})(jQuery);

我的问题是即使出现错误,结果也会被缓存(例如:主机暂时无法访问(。我不希望这种情况发生。

我以为只有在请求成功时才调用 done(( 函数,但事实并非如此。我应该添加一个 cache[date].fail((,将自身设置为 null 吗?我的意思是:

return cache[date].done(function(myData) {
    return new Promise(function(resolve,reject) {
        resolve(myData);
    });
}).fail(function(myData) {
    cache[date] = null;
    return new Promise(function(resolve,reject) {
        reject(myData);
    });
});

以下是在另一个模块中调用我的请求服务的方式:

requestService.fetchData(myDate).done(function(myData) {
    // code when successful
}).fail(function(d, textStats, error) {
    // error
});

donefail不支持链接回调结果,您的return new Promise绝对没有意义。此外,看起来好像您正在尝试使用 Promise 构造函数反模式。您的代码所做的只是按原样返回 ajax 承诺(它可以工作,因为您可以链接到它(。

即使出现错误,也会缓存结果

是的 - 通过存储承诺,整个请求结果被缓存,而不仅仅是在成功案例中。

我是否应该添加一个拒绝处理程序,将自身设置为 null?

是的,这正是您需要做的:

var requestService = (function($) {
    var cache = {};
    function get(date) {
        var params = date ? {'date': date} : {};
        return $.getJSON('http://my/url', params);
    }
    function fetchData(date) {
        if (!cache[date]) {
            cache[date] = get(date);
            cache[date].fail(function(err) {
                cache[date] = null; // retry next time
            });
        }
        return cache[date];
    }
    return {
        fetchData: fetchData
    };
})(jQuery);

如果要返回本机承诺,请使用

function fetchData(date) {
    if (!cache[date]) {
        cache[date] = Promise.resolve(get(date)).catch(function(err) {
            cache[date] = null; // retry next time
            throw err;
        });
    }
    return cache[date];
}

好吧,没关系,该代码进行了一些调整。在我的 fetchData 方法中,我正在检查对象是否为空(因此未定义为空(,并且我添加了一个 fail(( 方法,该方法使缓存[日期]无效。我现在执行以下操作:

var requestService = (function($) {
    var cache = {};
    var get = function(date) {
        var params = date ? {'date': date} : {};
        return $.getJSON('http://my/url', params, function( result ){});
    };
    var fetchData = function(date) {
        // now also checks for null
        if ($.isEmptyObject(cache[date])) {
            cache[date] = get(date);
        }
        return cache[date].done(function(myData) {
            return new Promise(function(resolve,reject) {
                resolve(myData);
            });
        }).fail(function(myData) {
        return new Promise(function(resolve,reject) {
            // nullifies cache[date]
            cache[date] = null;
            reject(myData);
        });
    };
    return {
        fetchData: fetchData
    };
})(jQuery);

最新更新