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

Javascript 如何避免手动缓存返回错误的请求?,javascript,jquery,module-pattern,Javascript,Jquery,Module Pattern,我创建了一个模块(遵循Javascript的模块模式),用于发出http请求、缓存并返回结果: var requestService = (function($) { var cache = {}; var get = function(date) { var params = date ? {'date': date} : {}; return $.getJSON('http://my/url', params, function( resu

我创建了一个模块(遵循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()函数,但事实并非如此。是否应添加缓存[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的方式:

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

好的,不管怎样,代码经过了一些调整。在我的fetchData方法中,我正在检查对象是否为空(未定义或为null),并添加了一个fail()方法,该方法使缓存[date]为空。我现在做以下工作:

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);

done
fail
不支持链接回调结果,您的
返回新承诺
是毫无意义的。此外,它看起来好像您正在尝试使用。您的代码所做的只是按原样返回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];
}

谢谢你的提醒!我确实是promise API的新手,这段代码更干净。