MVC2 一次异步调用,多次异步更新
Posted
技术标签:
【中文标题】MVC2 一次异步调用,多次异步更新【英文标题】:MVC2 One Async Call, Multiple Async Updates 【发布时间】:2011-01-22 09:37:20 【问题描述】:我的页面上有一个操作,然后需要连续执行 3 个长(每个几秒)操作。但是,在执行每个操作之后,我希望控制器返回一个局部视图并使用状态更新页面(让用户了解情况,我发现如果人们知道这些事情正在发生,他们就会减少担心)。有没有一种 MVC 的“方式”来做到这一点,还是我应该只使用 jQuery 来做到这一点?
谢谢。
【问题讨论】:
【参考方案1】:您将希望使用 jQuery 对三个单独的控制方法发出三个单独的调用,并在返回时分别更新页面的三个区域。
“捆绑”调用的唯一方法是将所有调用合并为一个,但您无法在返回多个调用时将返回值返回给客户端(几乎就像流式传输一样,没有任何监听返回第一个结果集后,客户端将关闭该连接)。
【讨论】:
我在兜了一圈之后得出了这个结论,但是现在这给我带来了不同的问题。 IE 很愚蠢,因为它不会在您运行 javascript 时更新 UI(或让您选择强制更新)。因此,当我尝试进行 3 次同步 JQuery.ajax 调用时,我的 UI 会被冻结,直到它们全部完成。现在这个网站上的其他帖子说解决方案是使操作异步,但是嗯......如果顺序无关紧要,我不会使用同步......有什么想法吗? @BitFiddler:对 jQuery 上的 ajax 方法的调用是异步的(您正在提供回调,对吗?)。如果您看到屏幕冻结,那么我猜测 UI 更新被阻塞,而不是异步调用。 不,调用不是异步的。我需要它们以特定的顺序发生(我正在使用的系统是独立的,但相互依赖......不要让我开始)。所以显然 IE 在所有脚本运行完成之前不会更新它的 DOM,这是我的问题 :-(【参考方案2】:所以我创建了一个小技巧,似乎可行:
在客户端我有:
function onClickHandler()
updateUI("Beginning Batch...");
setTimeout(klugeyClick, 0);
function klugeyClick()
$.ajax( type: "GET", dataType: "json", url: "/ControllerName/Action1", success: function(msg) updateUI(msg) , async: false, error: function(XMLHttpRequest, textStatus, errorThrown) updateUI("Action1 Error: " + XMLHttpRequest + " -- " + textStatus + " ---- " + errorThrown); );
setTimeout(klugeyClick2, 0);
function klugeyClick2()
$.ajax( type: "GET", dataType: "json", url: "/ControllerName/Action2", success: function(msg) updateUI(msg) , async: false, error: function(XMLHttpRequest, textStatus, errorThrown) updateUI("Action2 Error: " + XMLHttpRequest + " -- " + textStatus + " ---- " + errorThrown); );
setTimeout(klugeyClick3, 0);
function klugeyClick3()
$.ajax( type: "GET", dataType: "json", url: "/ControllerName/Action3", success: function(msg) updateUI(msg) , async: false, error: function(XMLHttpRequest, textStatus, errorThrown) updateUI("Action3 Error: " + XMLHttpRequest + " -- " + textStatus + " ---- " + errorThrown); );
function updateUI(result)
$("#UIelement").text(result);
在服务器端我有:
Function Action1() As JsonResult
System.Threading.Thread.Sleep(3000)
Return Json("Operation One Complete...")
End Function
Function Action2() As JsonResult
System.Threading.Thread.Sleep(3000)
Return Json("Operation Two Complete...")
End Function
Function Action3() As JsonResult
System.Threading.Thread.Sleep(3000)
Return Json("Operation Three Complete...")
End Function
现在我有两个问题。首先,我想要一条显示“批处理完成”但遵循相同模式的后续消息,并且只需添加另一个“klugeyClick”并调用 UpdateUI(带或不带 seTimeout)会导致最后的操作消息不显示.我认为 jQuery.ajax 方法中的回调使这个 kluge 以某种方式工作,但没有 ajax 调用,我无法放置任何后续消息。
下一个问题是,虽然我的所有调用都到达了我的 web 服务并且返回 json 结果很好,但我总是从 jQuery 回调返回一个错误。任何想法为什么会这样?
谢谢。
【讨论】:
【参考方案3】:您的“kludgy”解决方案有效的原因是setTimeout()
方法创建了一个事件。因此,您的逻辑是:
-
更新用户界面
步骤 1 的设置事件:
-
开始“ajax”调用
等待“ajax”完成
步骤 2 的设置事件
-
开始“ajax”调用
等待“ajax”完成
步骤 3 的设置事件
-
开始“ajax”调用
这正是ajax()
的回调功能的用途。
function Step1()
$.ajax(
type: "GET",
dataType: "json",
url: "/ControllerName/Action1",
success: function(msg)
updateUI(msg);
Step2(); // call step 2 here!
,
async: true, // don't block the UI
error: function(XMLHttpRequest, textStatus, errorThrown)
updateUI("Action1 Error: " + XMLHttpRequest + " -- " + textStatus + " ---- " + errorThrown);
);
function Step2()
// similar to step one
【讨论】:
但是,如果我将这些 Async ajax 调用中的 3 个串在一起,它们总是会按顺序返回吗? 我刚刚对其进行了测试,如果我要使用您的解决方案,它将无法按预期工作。当 Async 设置为 true 时,它们将乱序到达,在我的解决方案中,它们不会乱序到达。本质上,我在等待响应时解锁界面,以便我可以更新它......这就是我想要的。但是,如果没有在最后对一些虚拟的 web 服务方法进行另一个 Ajax 调用,我不能再次使用这个技巧来说整个批处理已经完成。此外,由于某种原因,结果仍然没有成功返回。 它们将始终以正确的顺序并一个接一个地触发,因为直到 Step1 成功完成后才会调用 Step2。我不会再打电话只是为了得到“批处理完成”消息。只需以某种方式将其标记到第三条消息的末尾即可。即“操作三完成......批量完成” 乔尔,你是对的。所以这简化了我的代码,但无助于在最后显示一条消息说“批处理完成”我尝试添加:setTimeout(updateUI("FINISHED"), 3000);在最后一步,但这会导致最后一次服务调用的结果被跳过。另外,知道为什么 json 调用总是作为“未知错误”返回吗? javascript 没有线程。这是 setTimeout 的第一个错误。你和你都有事件,但在给定时间只有一个代码线程在运行。【参考方案4】:据我所知,让后续消息以我想要的方式显示的唯一方法(即在我上次操作后的几秒钟)是有一个我称之为返回的虚拟 web 服务方法延迟后的最后一条消息......很糟糕。
现在我的最后一个问题是,我对 jsonResult 操作的所有调用都返回给客户端的 textStatus 为“错误”。现在根据文档,这意味着一个 http 错误,但是如果在服务器端正确调用该方法并且生成了 Json 结果(通过在服务器上设置断点进行验证),怎么会出现 http 错误?
【讨论】:
最后一个问题最终与 json 和 'get' 操作有关。显然,需要在某处设置一些设置以允许这样做(它似乎不支持开箱即用)。我刚改用 Post,一切都很顺利。【参考方案5】:对于我们的网站,我们有一个需要时间的大操作。该动作由子动作组成,我们汇总结果并构建一个漂亮的视图。
一年前:
我们按顺序执行此操作:action1,然后是 action2,等等。 我们有典型的页面:请稍候。可以帮助你的技巧:
我们在服务器端执行并行请求。 我们在结果页面中等待结果。那里的 javascript 需要一些时间来加载,所以当服务器搜索时,我们会加载页面。 我们每秒都会询问服务器:你完成了吗?随着不同操作的完成,我们会得到部分结果。我不知道你是否可以将所有这些东西都应用到你的问题上,但其中一些真的很好。
我们不使用 MVC,我们使用一些带有 jQuery 和 ajax 的 asmx 服务。
【讨论】:
以上是关于MVC2 一次异步调用,多次异步更新的主要内容,如果未能解决你的问题,请参考以下文章