情境:
所以我有一个javascript组件基本上包含一些全局数据列表的实例(在我的实际应用程序中,它存在于Flux Store中,但为了简单起见,我只是将其称为全局变量)。 / p>
它包含通过对REST API进行AJAX调用来添加/删除数据的函数。
的设计
由于我希望用户能够立即查看更新的列表,而不是等到Ajax成功回调,我正在执行“乐观更新”。
也就是说,我在执行实际的AJAX调用之前更新列表,同时在localStorage中保留列表的原始副本以防AJAX调用失败。
(1)如果AJAX调用成功,则使用API响应更新列表(基本上应与乐观更新的列表相同)
(2)如果AJAX调用失败,则通过从localStorage检索原始副本来撤消乐观更新。
这是我的实施:
// Some global data list
var myData = ["data1", "data2", ...];
function addData(dataToAdd) {
// Store original in cache before optimistic update
localStorage.set("MY_DATA", myData);
// Do optimistic update
myData = myData.concat(dataToAdd);
$.ajax({
url: REST_API_ADD,
method: "POST",
data: { data: dataToAdd },
dataType: "json",
success: function(response) {
// API returns the updated list when success
myData = response;
},
error: function(xhr, status, err) {
console.log(err);
// Cancel optimistic update and retrieve old data from cache
myData = localStorage.get("MY_DATA");
}
});
}
function deleteData(dataToDelete) {
// Store original in cache before optimistic update
localStorage.set("MY_DATA", myData);
// Do optimistic update
// I'm using Underscore.js here to delete data from list
myData = _.without(
myData,
_.findWhere(myData, {id: dataToDelete.id})
);
$.ajax({
url: REST_API_DELETE,
method: "DELETE",
data: { data: dataToDelete },
dataType: "json",
success: function(response) {
// API returns the updated list when success
myData = response;
},
error: function(xhr, status, err) {
console.log(err);
// Cancel optimistic update and retrieve old data from cache
myData = localStorage.get("MY_DATA");
}
});
}
这个想法有什么问题吗?
我主要担心的是当用户几乎同时执行ADD和DELETE操作时可能出现的竞争条件。
我已经考虑过可能的场景,但似乎并发性在我的情况下不是问题,因为回调函数永远不会修改localStorage。他们所做的只是“得到”。
有人能想到我的设计可能会导致问题的情况吗?
整体上这是一个糟糕的设计吗?如果是这样,那么你可以建议一种替代方法吗?
由于
答案 0 :(得分:0)
我主要担心的是用户可能出现的竞争状况 几乎同时执行ADD和DELETE操作..
这里不应该担心,因为在并行方面,从UI线程执行的AJAX不是异步。 Web浏览器使用执行队列,其中每个排队的操作同步出列。
例如,您永远不会同时修改DOM并执行AJAX请求。实际上,UI任务比AJAX更优先,但无论如何它们将被逐一执行。
AFAIK,你只有一次机会遇到并发问题:Web workers。除非你使用它们,否则你绝对安全。
答案 1 :(得分:0)
我认为这不是一个糟糕的设计,但您仍然可以更好地控制用户。至少你可以阻止他们在ajax呼叫等待成功时采取另一个动作。
我可以想到一个问题:如果你正在处理大量数据,写入和读取localStorage可能会导致性能问题。
除此之外,你的方法应该没有任何问题。