我创建了一个模块(遵循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
});
done
和fail
不支持链接回调结果,您的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);