jqXHR.abort() 没有取消请求但导致浏览器无响应
jqXHR.abort() not cancelling the request but causing the browser to be unresponsive
我有一个 jQuery 对话框,我在进行 ajax 调用时使用它。我希望能够在对话框关闭时中止当前请求。为此,我定义了一个名为 currentRequest 的全局变量,每次设置 ajax 请求时,我都会将其分配给该变量。在对话框的关闭事件中,我检查 currentRequst
是否不等于 undefined
,如果是,我调用 currentRequst.abort()
。但这似乎不起作用,因为我无法重新加载页面。我必须等到接收响应所需的时间已经过去。这是对话的一部分:
...
close:function(event,ui){dialogClosehandler();}
...
function dialogClosehandler(){
alert('Dialog is closed');
if(currentRequest!=undefined)
currentRequest.abort();
}
正如我所说,这是行不通的。但是,如果我在设置 ajax 调用时正确地中止它,那么它就可以工作。
currentRequest=$.ajax({
url: "/GetData",
type: 'POST',
data: {} ,
contentType: 'application/json',
dataType: 'json',
}).abort();
注意 .abort()
。
有什么我想念的吗?
编辑:我想我需要把问题再扩展一点。我没有任何问题,例如,只是提醒你好的按钮或将用户带到 google.com 的 link。但是假设我点击了一个发出另一个 ajax 请求的按钮,或者尝试提交表单,所以任何会向服务器发送请求的东西,在这种情况下它不会有任何效果,除非有一段时间过去了。
编辑 2 出于测试目的,我创建了 2 个函数:
currentXHR=null;
function startAjax(){
var url="/StartAjax";
currenXHR=$.get(url,{},function(){alert('Ajax launched');});
}
function cancelAjax(){
currentXHR.abort();
}
这是服务器端方法(它是 C#,ASP.NET MVC):
public void StartAjax()
{
System.Threading.Thread.Sleep(10000);
}
我有两个按钮,名为开始和取消。当我单击开始并等待响应时,我会在 10 秒后收到 "Ajax launched" 警报。但是,如果我在开始请求后立即单击取消,我最终不会收到任何警报,但除非经过 10 秒,否则我仍然无法刷新页面。如您所见,ajax 请求是异步的(否则我将无法单击取消按钮),因此此问题与其他问题有关。
经过大量挖掘和搜索后,我得出的结论是这是预期的行为,因为尽管 AJAX 请求本身是异步的,但这并不意味着服务器也会处理此请求单独的线程。因此,只要主线程忙于处理前一个请求,它就不会继续处理另一个请求。因此,当按下重新加载按钮时,确实会向服务器发送一个新请求,但只有在完成前一个请求后才会返回新请求的响应。所以对我来说,最好的选择是在单独的线程上处理 ajax 请求。这有两个优点:
- 由于主线程没有阻塞,新请求的响应不需要等待。
- 通过使用CancellationToken我们还可以通知服务器取消处理某个请求的响应,避免资源浪费。
我认为 this article by Rick Anderson 是做到这一点的绝妙指南。
我有一个 jQuery 对话框,我在进行 ajax 调用时使用它。我希望能够在对话框关闭时中止当前请求。为此,我定义了一个名为 currentRequest 的全局变量,每次设置 ajax 请求时,我都会将其分配给该变量。在对话框的关闭事件中,我检查 currentRequst
是否不等于 undefined
,如果是,我调用 currentRequst.abort()
。但这似乎不起作用,因为我无法重新加载页面。我必须等到接收响应所需的时间已经过去。这是对话的一部分:
...
close:function(event,ui){dialogClosehandler();}
...
function dialogClosehandler(){
alert('Dialog is closed');
if(currentRequest!=undefined)
currentRequest.abort();
}
正如我所说,这是行不通的。但是,如果我在设置 ajax 调用时正确地中止它,那么它就可以工作。
currentRequest=$.ajax({
url: "/GetData",
type: 'POST',
data: {} ,
contentType: 'application/json',
dataType: 'json',
}).abort();
注意 .abort()
。
有什么我想念的吗?
编辑:我想我需要把问题再扩展一点。我没有任何问题,例如,只是提醒你好的按钮或将用户带到 google.com 的 link。但是假设我点击了一个发出另一个 ajax 请求的按钮,或者尝试提交表单,所以任何会向服务器发送请求的东西,在这种情况下它不会有任何效果,除非有一段时间过去了。
编辑 2 出于测试目的,我创建了 2 个函数:
currentXHR=null;
function startAjax(){
var url="/StartAjax";
currenXHR=$.get(url,{},function(){alert('Ajax launched');});
}
function cancelAjax(){
currentXHR.abort();
}
这是服务器端方法(它是 C#,ASP.NET MVC):
public void StartAjax()
{
System.Threading.Thread.Sleep(10000);
}
我有两个按钮,名为开始和取消。当我单击开始并等待响应时,我会在 10 秒后收到 "Ajax launched" 警报。但是,如果我在开始请求后立即单击取消,我最终不会收到任何警报,但除非经过 10 秒,否则我仍然无法刷新页面。如您所见,ajax 请求是异步的(否则我将无法单击取消按钮),因此此问题与其他问题有关。
经过大量挖掘和搜索后,我得出的结论是这是预期的行为,因为尽管 AJAX 请求本身是异步的,但这并不意味着服务器也会处理此请求单独的线程。因此,只要主线程忙于处理前一个请求,它就不会继续处理另一个请求。因此,当按下重新加载按钮时,确实会向服务器发送一个新请求,但只有在完成前一个请求后才会返回新请求的响应。所以对我来说,最好的选择是在单独的线程上处理 ajax 请求。这有两个优点:
- 由于主线程没有阻塞,新请求的响应不需要等待。
- 通过使用CancellationToken我们还可以通知服务器取消处理某个请求的响应,避免资源浪费。
我认为 this article by Rick Anderson 是做到这一点的绝妙指南。