javascript - AJAX 查询并不总是一致地更新信息
问题描述
我在 AJAX 更新页面时遇到了一些问题。数据库中的实际数据会更新,但这并不总是实时反映在网页上。
例如,我有以下事件:
$("#add_note").click(function(e) {
//e.preventDefault();
$("#add_note_form").validate({
rules: {
contact_note: {
required: true
}
},
submitHandler: function(form) {
contact.modal_update({
'obj' : $('#add_note_form'),
'uri' : '/contact/add_note/'
});
}
});
});
此函数在创建新便笺时调用回调以首先验证表单字段,然后如果成功则在单独的类中调用回调以进行更新。请参阅下面的 modal_update 类:
// Update modal
this.modal_update = function(data)
{//
// Declare a few variables for the data object we've received
obj = data.obj // The form element to serialize
uri = data.uri;
// Get the form ID from the data-target attribute
id = obj.attr('data-target');
// URL to send to
url = this.site_url + uri + id;
// The form object
this.post_data(obj.serialize(),url);
// Hide Modal
obj.closest('.modal').modal('hide');
// Refresh
this.refresh();
}
然后找出正确的 ajax 路由并在同一个类中调用 ajax 回调:
// AJAX post
this.post_data = function(obj,uri)
{
$.ajax({
data: obj,
dataType: 'json',
type: 'post',
url: uri,
headers: { "cache-control": "no-cache" },
cache: false,
success: function (response) {
if (response.success == true)
{
$("#alert_success .msg").html(response.message);
$("#alert_success").fadeIn(200).delay(2000).fadeOut(200);
}
else
{
$("#alert_error .msg").html(response.error);
$("#alert_error").fadeIn(200).delay(2000).fadeOut(200);
console.log(response.error);
}
}
});
}
然后我运行另一个类回调来“刷新”页面上所有元素中的数据:
this.refresh = function()
{
// Refresh the ajax requests
this.get_contact_data();
this.get_notes();
this.get_contact_log();
this.get_contact_tasks();
}
此类重新加载在页面加载时运行的函数,以将初始数据获取到页面上的表/字段中。请参阅下面的“get_notes”:
// Get notes
this.get_notes = function()
{
// Get all notes and populate table
var log_uri = this.site_url + "/contact/get_notes/" + this.contact_id;
this.get_data(log_uri,function(data) {
notes = $("#contact_notes ul");
notes.empty("");
// Populate the contact fields, assuming there is a result to play with
if (data != false) {
//alert(JSON.stringify(data));
$("#notes-tab .count").html("(" + data.length + ")");
$.each( data, function( key, value ) {
notes.append("<li class='list-group-item' modal-id='editNoteModal' data-target='" + value.ID + "'><div class='row'><div class='col-lg-3'><i class='fa fa-sticky-note mr-3'></i>" + value.timestamp + "</div><div class='col-lg-7'>" + value.note + "</div><div class='col-lg-2'><a href='#' class='edit mr-3'><i class='fa fa-edit mr-1'></i>Edit</a><a href='#' class='delete'><i class='fa fa-times mr-1'></i>Remove</a></div></div></li>");
});
console.log('Notes loaded');
} else {
notes.append("<li>There are currently no notes for this contact</li>");
}
});
}
现在的问题:
由于某种原因,这不会实时一致地更新。数据在服务器端更新得很好,但在客户端更新/刷新并不总是更新。我可能会添加一个注释并获得正确的更新响应,但刷新方法似乎正在接收旧数据并且总是落后一个注释。所以下次我添加注释时,我之前添加的注释就会出现,依此类推。
我遇到的另一个问题是方法似乎堆叠在每个事件上,所以如果我添加一个注释(或其他方法之一),我会看到控制台说“加载了注释”,但在第二个注释上它说“加载了注释”两次,然后在第 3 个音符上添加 3 次,以此类推。
我确信我的代码设计中一定存在致命缺陷,但我对 javascript/jquery 的经验不足,无法注意到我出错的方向,因此我可以修复它。
我认为这是 ajax 缓存的问题,没有刷新结果,所以我将 ajax 请求调整为无缓存,并且不发送缓存标头。我在沼泽中奔跑。
解决方案
在您的情况下,您的刷新代码将始终在您的数据更新之前运行。因为 ajax 是异步的,所以 ajax 后面和下面的代码将总是几乎在你的 ajax 运行时执行。
在您运行post_data
函数以调用 API 时,该refresh
函数也开始运行。所以它是在你的数据更新之前完成的。
您应该在 ajax 回调中运行刷新函数。例如:
this.post_data = function(obj,uri, callback)
{
$.ajax({
data: obj,
dataType: 'json',
type: 'post',
url: uri,
headers: { "cache-control": "no-cache" },
cache: false,
success: function (response) {
if (response.success == true)
{
$("#alert_success .msg").html(response.message);
$("#alert_success").fadeIn(200).delay(2000).fadeOut(200);
}
else
{
$("#alert_error .msg").html(response.error);
$("#alert_error").fadeIn(200).delay(2000).fadeOut(200);
console.log(response.error);
}
callback();
}
});
}
在 中modal_update
,您将刷新函数作为回调传递给 post_data:
this.modal_update = function(data)
{//
// Declare a few variables for the data object we've received
obj = data.obj // The form element to serialize
uri = data.uri;
// Get the form ID from the data-target attribute
id = obj.attr('data-target');
// URL to send to
url = this.site_url + uri + id;
// The form object
this.post_data(obj.serialize(),url, this.refresh);
// Hide Modal
obj.closest('.modal').modal('hide');
}
您应该阅读有关异步 ajax 的更多信息。您可以使用其他棘手的解决方案 setTimeout 来运行this.refresh
,但我不建议您这样做,因为您不确定更新何时完成。
推荐阅读
- javascript - DropzoneJS - 事件中的异步任务未按预期工作
- laravel - 如何在 laravel eloquent 模型中优化以下查询?
- python - Python pyplot - 在条形图标签之间绘制圆弧图
- python-3.x - 创建活动时出现 Google 日历 API 400 错误
- pandas - 为什么 pandas.melt 会弄乱我的 dtypes?
- mysql - 如何仅使用时间戳字段的日期部分更新日期字段?
- javascript - 避免从 JS 和 React 上的 datapicker 中选择今天之前的日期,而不包括今天
- python - OpenCV,更改为图像中最接近的颜色
- python - 在 Anaconda Jupyter 中使用 wget 获取 csv 文件
- java - 如果我们使用 Spring Data JPA 更改其结构,如何处理数据库