如何避免手动缓存返回错误的请求?
How to avoid manually caching a request that returned an error?
我创建了一个模块(遵循 Javascript 的模块模式),它发出 http 请求、缓存和 returns 结果:
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 方法中,我正在检查对象是否为空(因此未定义 或 为空),并且我添加了一个使缓存 [date] 无效的 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);
done
和 fail
不支持链接回调结果,你的 return new Promise
绝对没有意义。此外,您似乎正在尝试使用 Promise
constructor antipattern。您的代码所做的只是 return ajax 按原样承诺(有效,因为您可以链接到它)。
the results are cached even if there's an error
是 - 通过存储承诺,整个请求结果都会被缓存,而不仅仅是在成功的情况下。
Should I add a rejection handler, setting itself to 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);
如果你想return一个本地承诺,使用
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];
}
我创建了一个模块(遵循 Javascript 的模块模式),它发出 http 请求、缓存和 returns 结果:
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 方法中,我正在检查对象是否为空(因此未定义 或 为空),并且我添加了一个使缓存 [date] 无效的 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);
done
和 fail
不支持链接回调结果,你的 return new Promise
绝对没有意义。此外,您似乎正在尝试使用 Promise
constructor antipattern。您的代码所做的只是 return ajax 按原样承诺(有效,因为您可以链接到它)。
the results are cached even if there's an error
是 - 通过存储承诺,整个请求结果都会被缓存,而不仅仅是在成功的情况下。
Should I add a rejection handler, setting itself to 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);
如果你想return一个本地承诺,使用
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];
}