我遇到了一个问题,经过几个小时的搜索后,当我偶然发现可以将ajax-call的async-option设置为false时,我已经解决了这个问题。我的代码现在完全按照我的预期运行,但我想知道我的解决方案是否良好,或者是否能以更好的方式解决。如果我的解决方案不好,你为什么这么认为呢?异步vs同步,什么是最好的?是否应该尽可能地努力使用异步调用?
var pageIndex = 0;
(function () {
GetData();
$(window).scroll(function () {
if ($(window).scrollTop() ==
$(document).height() - $(window).height()) {
GetData();
}
});
})();
$.ajax({
type: 'GET',
url: '/Blog/GetPostsByBlogId',
data: { "id": @Model.First().ReqBlog.Id, "pageindex": pageIndex },
dataType: 'json',
success: function (response) {
DisplayData(response);
},
beforeSend: function () {
$("#progress").show();
},
complete: function () {
$("#progress").hide();
},
error: function (response) {
alert("Error while retrieving data!");
}
});
在成功中我调用了以下函数:
function DisplayData(response)
{
if (response != null) {
$.each(response, function (i, post) {
$.ajax({
async: false,
url: "/Blog/GetPostPartialView",
data: post,
type: "POST",
success: function (response) {
$("#posts-container").append(response);
}
});
});
pageIndex++;
}
}
没有" async:false"每次刷新时,数据都以随机顺序显示。使用" async:false"数据每次都以正确的顺序显示。
修改:
我使用以下解决方案来避免使用async:false。
我的DisplayData功能现在看起来像这样:
function DisplayData(response)
{
if (response != null) {
$.each(response, function (i, post) {
$('#posts-container').append($('<div>').load("/Blog/GetPostPartialView", { Id: post.Id, Title: post.Title, Body: post.Body, Created: post.Created, Updated: post.Updated, Views: post.Views, Blog: post.Blog, Tags: post.Tags, Comments: post.Comments, Author: post.Author }));
});
pageIndex++;
}
}
答案 0 :(得分:2)
async: false
是可怕的练习。这是一个糟糕的解决方案,并且极少数情况下它会有效。实际上它太糟糕了,如果你检查控制台,你会看到一个浏览器警告告诉你不要使用它。
关于您的订单被随机化的问题,因为循环中的AJAX请求都在不同的时间完成。要解决此问题,您应删除async: false
并删除:
在客户端上将返回的数据整理在一起,然后在显示之前手动sort()
。
更改您的服务器代码,以便在单个AJAX调用中传递所有数据,然后您可以按正确的顺序返回所有必需的信息。
第二个选项是到目前为止更好的解决方案,因为它还避免了由于您(N个博客帖子+ 1)请求而导致当前正在发生的服务器的DDOS。目前正在淹没它。
答案 1 :(得分:0)
async = false属性将导致阻止执行javascript代码流,这通常是非常糟糕的做法。当您使用ajax async = true时,您无法确定多个ajax调用的顺序。如果您无法在服务器端执行任何操作,则可以将已审阅的数据收集到客户端的数据结构中,并根据需要进行排序。您也可以在完成之前的ajax调用时调用即将发布的ajax调用。这样,您就可以按照发送ajax请求的顺序获得结果。