chr*_*sen 2 javascript json fetch
我有一个应用程序可以进行很多异步操作fetch调用,其中一些是相同的。
我有一个超集函数fetch(例如fetchPlus),通过根据参数为每个请求创建一个伪唯一标识符。这样,我就可以存储结果sessionStorage并访问它。
function fetchCacheStore(hash) {\n const storeItem = \'fetch_\' + hash;\n return {\n getCache: function () {\n return JSON.parse(sessionStorage.getItem(storeItem));\n },\n\n setCache: function (data) {\n sessionStorage.setItem(storeItem, JSON.stringify(data));\n setTimeout(function () { sessionStorage.removeItem(storeItem); }, 25); // Clear the cache item shortly after\n },\n };\n}\n\nfunction fetchPlus() {\n const stringHasher = function (s) { // Adapted from /sf/ask/533152301/#comment94234739_7616484\n for (var i = h = 0; i < s.length; i++) {\n h = Math.imul(31, h) + s.charCodeAt(i) | 0;\n }\n return btoa(h);\n }\n\n let thisCallDetails = JSON.stringify(Array.prototype.slice.call(arguments).sort());\n let fetchCallHash = stringHasher(thisCallDetails);\n let fetchCache = fetchCacheStore(fetchCallHash);\n let fetchCacheGet = fetchCache.getCache();\n\n let promise;\n\n if (fetchCacheGet === null) { // The data is not cached\n promise = fetch(...arguments); // Create the fetch call\n promise.then(data => {\n data.close.json().then(content => {\n fetchCache.setCache(content);\n });\n }); // Store the result in the cache\n } else {\n let dataHeaders = { "status": 200, "Content-Type": "application/json" };\n promise = new Response(fetchCacheGet, dataHeaders); // Programatically create a Response\n }\n\n return promise;\n}\nRun Code Online (Sandbox Code Playgroud)\n\n除了当数据存在于 中时sessionStorage,我直接返回一个 JSON 对象,而不是Response, 之外,一切都运行良好,因此在我的代码中,当我执行如下调用时:
fetchPlus(url, params)\n .then(response => response.json())\n .then(data => \xe2\x80\xa6)\nRun Code Online (Sandbox Code Playgroud)\n\n我最终得到一个错误,让我知道我无法json()在response.
该行promise = new Response(fetchCacheGet, dataHeaders);可能不正确,但我不确定如何将数据“反转”为原始fetch调用中吐出的数据。也许我错过了一些明显的东西。或者也许这一切都是错误的。
我愿意接受建议,但这个应用程序已经设置完毕,因此.then(response => response.json())无法从代码库中删除所有内容。
另外,我知道我的代码不是同类中最好的,所以请原谅我。再次强调,只要是有建设性的建议,都持开放态度。
\n\n如果有人有几分钟的空闲时间,我很乐意帮助完成这项工作。
\n\n感谢@AuxTaxo下面的回答,我已经解决了我的问题。对于任何感兴趣的人,这里是更新的代码:
\n\nfunction fetchCacheStore(hash) {\n const storeItem = \'fetch_\' + hash;\n return {\n getCache: function () {\n return JSON.parse(sessionStorage.getItem(storeItem));\n },\n\n setCache: function (data) {\n sessionStorage.setItem(storeItem, JSON.stringify(data));\n setTimeout(function () { sessionStorage.removeItem(storeItem); }, 25); // Clear the cache item shortly after\n },\n };\n}\n\nfunction fetchPlus() {\n const stringHasher = function (s) { // Adapted from https://stackoverflow.com/questions/7616461/generate-a-hash-from-string-in-javascript/22429679#comment94234739_7616484\n for (var i = h = 0; i < s.length; i++) {\n h = Math.imul(31, h) + s.charCodeAt(i) | 0;\n }\n return btoa(h);\n }\n\n let thisCallDetails = JSON.stringify(Array.prototype.slice.call(arguments).sort());\n let fetchCallHash = stringHasher(thisCallDetails);\n let fetchCache = fetchCacheStore(fetchCallHash);\n let fetchCacheGet = fetchCache.getCache();\n\n let promise;\n\n if (fetchCacheGet === null) { // The data is not cached\n promise = fetch(...arguments); // Create the fetch call\n promise.then(data => {\n data.close.json().then(content => {\n fetchCache.setCache(content);\n });\n }); // Store the result in the cache\n } else {\n let dataHeaders = { "status": 200, "Content-Type": "application/json" };\n promise = new Response(fetchCacheGet, dataHeaders); // Programatically create a Response\n }\n\n return promise;\n}\nRun Code Online (Sandbox Code Playgroud)\r\n我认为data.close.json().then是一个拼写错误data.clone().json().then。
new Response()期望(以及其他选项)一个字符串,但您传递给它一个对象。响应正文最终被设置为"[object Object]",这.json()会导致阻塞。
您可以通过在将对象传递给 Response 构造函数之前将其字符串化来解决该问题,但更好的解决方案是尽可能长时间地使用字符串。您的响应主体是字符串,存储对象存储字符串,因此将结果存储response.text()在缓存中而不是response.json().
另外,您只将结果缓存25 毫秒,因此sessionStorage跨页面刷新保留数据的优势似乎没有用处。只需使用一个普通对象作为缓存即可。并且dataHeaders应该是{ "status": 200, headers: { "Content-Type": "application/json" } }。
| 归档时间: |
|
| 查看次数: |
4990 次 |
| 最近记录: |