我必须向HTML页面上的js对象添加一个数据结构列表。我在服务器端有一个数据结构列表,每个结构由data-key
标识。js函数循环data-keys
的列表,该函数使用对应的data-key
从async_cache
中一次获取一个结构。列表中可能有多个相同的data-keys
1.如果async_cache
在data-key
之前不具有data-structure
,则它异步获取并将其添加到该高速缓存。
1.如果async_cache
通过data-key
具有data-structure
,则它立即返回它。
1.如果X1 M11 N1 X已经请求获取X1 M12 N1 X,并且在数据到达之前具有对同一X1 M13 N1 X的另一请求,则它必须不复制该请求,而是等待直到数据到达。
到目前为止,我已经构造了下面的代码(作为讨论的例子)。实际的环境不能共享。
<?php
switch($_GET['--action'] ?? false){
case 'data-structure':{
$data_group = [
'data-01' => ['a' => 'info-01', 'b' => 'extra-01'],
'data-02' => ['a' => 'info-02', 'b' => 'extra-02'],
'data-03' => ['a' => 'info-03', 'b' => 'extra-03'],
'data-04' => ['a' => 'info-04', 'b' => 'extra-04'],
'data-05' => ['a' => 'info-05', 'b' => 'extra-05'],
];
if($data_struct = ($data_group[$_GET['key'] ?? false] ?? false)){
\header('Content-Type: application/json');
echo json_encode(['status'=> 'ok', 'data' => $data_struct], JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit();
} else {
http_response_code(404);
echo json_encode('Not Found', JSON_PRETTY_PRINT|JSON_UNESCAPED_SLASHES);
exit();
}
} break;
}
?>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta key="viewport" content="width=device-width, initial-scale=1.0">
<title>JS Async Data Buffer Experiment</title>
</head>
<body>
<div class="container">
</div>
<script>
xui = {};
xui.async_cache = {
async async_get_await(url = '', options = {}){
// Default options are marked with *
const response = await fetch(
url,
{
method: 'GET', // *GET, POST, PUT, DELETE, etc.
mode: options.mode || 'same-origin', // no-cors, *cors, same-origin
cache: options.cache || 'no-cache', // *default, no-cache, reload, force-cache, only-if-cached
credentials: options.credintials || 'same-origin', // include, *same-origin, omit
redirect: options.redirect || 'follow', // manual, *follow, error
referrerPolicy: options.referrerPolicy || 'no-referrer', // no-referrer, *no-referrer-when-downgrade, origin, origin-when-cross-origin, same-origin, strict-origin, strict-origin-when-cross-origin, unsafe-url
}
);
return response.json(); // parses JSON response into native JavaScript objects;
},
get(action, key){
if(key in this){
return new Promise((resolve, reject) => {
resolve(this[key]);
});
} else {
return this.async_get_await(
`?--action=${action}&key=${key}`,
).then((r) => {
this[key] = r.data;
return this[key];
});
}
},
};
window.addEventListener('DOMContentLoaded', function(){
var list = [
'data-01',
'data-01',
'data-02',
'data-01',
'data-03',
'data-02',
'data-04',
'data-02',
'data-01',
];
list.forEach((key) => {
console.log({key});
xui.async_cache.get('data-structure', key).then((data) => {
console.log(data);
});
});
});
</script>
</body>
</html>
第1种和第2种情况已经解决了,但第3种情况是我遇到的问题。正如您所看到的,addEventListner
中的代码在接收数据或事件循环启动之前一次性执行。因此,对同一个data-key
发出了多个请求。
我正在寻找一个最低限度的方法。如果有一个编码功能在JS库没有使用第三方库-这将做得很好。
我还研究了Fetch-API
上该高速缓存选项,但这不是一个解决方案。
谢谢!
1条答案
按热度按时间shyt4zoc1#
感谢@Bergi我终于弄明白了!我重写了async_cache并继续简化...以下是我得到的结果(我还添加了一些测试按钮):
看起来我们可以利用promise中闭包的数据存储(或缓存),而且我们不需要await或async,至少在这个初级阶段是这样。